24考研数据结构-第五章:树与二叉树

目录

  • 第五章:树
  • 5.1树的基本概念
    • 5.1.1树的定义
    • 5.1.2 基本术语
    • 5.1.3 树的性质
  • 5.2二叉树的概念
    • 5.2.1 二叉树的定义与特性
    • 5.2.2 几种特殊的二叉树
    • 5.2.3 二叉树的性质
    • 5.2.4 完全二叉树的性质
    • 5.2.5 二叉树的存储结构
      • 1. 顺序存储
      • 重要的基本操作
      • 非完全二叉树
      • 2. 链式存储
      • 逆向寻找父节点
  • 5.3二叉树的遍历和线索二叉树
    • 5.3.1二叉树的遍历
      • 1. 先序遍历(根左右 NLR)
      • 2. 中序遍历(左根右 LNR)
      • 3. 后续遍历(左右根 LRN)
      • 4. 求树的深度(递归应用)
      • 5. 非递归遍历
      • 6. 层次遍历
      • 7. 由遍历序列构造二叉树
    • 5.3.2线索二叉树
      • 1. 线索二叉树的概念与作用
      • 2.线索二叉树的存储结构
      • 3. 二叉树的线索化
        • 1. 中序线索化
        • 2. 先序线索化
        • 3. 后序线索化
      • 4. 线索树的寻找前驱后继的各种情况(多理解)
  • 5.4树、森林
    • 5.4.1树的存储结构
      • 1. 双亲表示法(顺序存储):
      • 2. 孩子表示法(顺序+链式)
      • 3. 孩子兄弟表示法(链式)
    • 5.4.2树、森林与二叉树的转换
    • 5.4.3树、森林的遍历
      • 1. 树的遍历
        • 先根遍历
        • 后根遍历
        • 层序遍历(队列实现)
      • 2. 森林的遍历
  • 5.5树与二叉树的应用
    • 5.5.1 哈夫曼树和哈夫曼编码
        • 1. 带权路径长度的定义
        • 2. 哈夫曼树的定义(最优二叉树,不唯一)
        • 3. 哈夫曼树的构造
        • 4. 哈夫曼树的特点
        • 5.哈夫曼编码(最短二进制前缀编码)
    • 5.5.2 并查集(双亲表示法)
      • 1. 并查集的存储结构
      • 2. 并查集的代码实现
        • 初始化
        • 并查
        • 时间复杂度
        • union操作的优化(不要瘦高的树)
        • 并查集的进一步优化(find的优化,压缩路径)
        • 优化总结
    • ~~5.5.3二叉排序树(BST)~~
      • 1. 二叉排序树的定义
      • 2. 查找操作
      • 3. 插入操作
      • 4. 二叉排序树的构造
    • 5.5.2平衡二叉树(AVL)

第五章:树

5.1树的基本概念

节点数 = 度的和+1或者节点数

5.1.1树的定义

在这里插入图片描述

树是n个结点的有限集

  • 空树:n=0
  • 根结点、分支结点、叶子结点
  • 非空树的特性
  • 子树

在n个结点的树中有n-1条边

5.1.2 基本术语

结点之间的关系描述

  • 祖先、子孙、双亲、兄弟结点(亲兄弟同父节点、堂兄弟同一层次)
  • 路径(路径只有从上往下,需要从下往上的就不存在路径
  • 路径长度(树根到每个节点的路径长度的总和

结点、树的属性描述

  1. 结点的层次(深度,默认从1)——从上往下
  2. 结点的高度——从下往上
  3. 树的高度——总共多少层
  4. 结点的度——有几个孩子
  5. 树的度——各结点的度的最大值

有序树(家谱,从左到右有次序不可以互换)、无序树(左右位置没有逻辑关系,可以互换)

森林(多颗互不相交的树的集合,允许有空森林,跟树一样节点数可以为0

森林与树的转换

  • 当森林的树拥有共同根节点就是一棵树

5.1.3 树的性质

  • 树中的结点数等于所有结点的度数之和加1。(这个1是根节点,因为每个节点的度代表他的直接子节点个数,这些全部相加就差根节点的个数也就是1

  • 在这里插入图片描述

  • 度为m的树第i层上至多有m^i-1个结点(这是因为树的度代表最多一个节点拥有的最多的子节点个数,所以至多就是指数级别的关系

度为m的数、m叉数的区别

  • m叉树,只要每个节点的孩子数小于等于m,并且不要求存在一个节点的度等于m,所以一棵二叉树也一定是一棵三叉树,四叉树·······
  • 度为m的树,一定要有一个节点的度是m,所以不可能是空树,对于m叉树来说就可以是空树
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    度为m,有n个节点的树:树的高度最高是,n-(m+1)+2 = n-m+1
    在这里插入图片描述

5.2二叉树的概念

5.2.1 二叉树的定义与特性

定义:
二叉树是n(n>=0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两颗互不相交的分别称作这个根的左子树和右子树的二叉树组成。

特点:

  • 每个结点最多有俩孩子(二叉树中不存在度大于2的结点)。
  • 二叉树可以是空集合,根可以有空的左子树和空的右子树。
  • 二叉树有左右之分,次序不能颠倒。(有序,且子树也是二叉树)
  • 在这里插入图片描述

5.2.2 几种特殊的二叉树

  1. 满二叉树:一颗深度为k且有2^k-1个结点的二叉树称为满二叉树。每一层上的结点数都达到最大。叶子全部在最低层。

  2. 完全二叉树:深度为k的具有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号为1~n的结点一 一对应时,称之为完全二叉树。(缺少的只会是最后一个节点,递归这种缺少才能满足,就是不能缺少8号节点,因为这样8后边的所有节点都会变换序号,与满二叉树不一样了
    在这里插入图片描述
    完全二叉树的最多且唯一一个度为1的节点一定有的是左孩子

  3. 二叉排序树
    在这里插入图片描述

  4. 平衡二叉树

在这里插入图片描述

5.2.3 二叉树的性质

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2.4 完全二叉树的性质

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2.5 二叉树的存储结构

1. 顺序存储

#define MaxSize 100

struct TreeNode{
   ElemType value; //结点中的数据元素
   bool isEmpty;   //结点是否为空
}

main(){
   TreeNode t[MaxSize];
   for (int i=0; i<MaxSize; i++){
      t[i].isEmpty = true;
   }
}


在这里插入图片描述

重要的基本操作

在这里插入图片描述
二叉树的顺序存储中,一定要把二叉树的结点编号与完全二叉树对应起来

非完全二叉树

在这里插入图片描述

2. 链式存储

每个节点有两个指针域,n个节点就有2n个指针域,但是只有n-1个指针域指向n-1个子节点,所以有n+1个空指针域
在这里插入图片描述

//二叉树的结点

struct ElemType{
   int value;
};

typedef struct BiTnode{
   ElemType data;          //数据域
   struct BiTNode *lchild, *rchild; //左、右孩子指针
}BiTNode, *BiTree;

//定义一棵空树
BiTree root = NULL;

//插入根节点
root = (BiTree) malloc (sizeof(BiTNode));
root -> data = {1};  //{}是必须的,因为这里对结构体初始化
root -> lchild = NULL;
root -> rchild = NULL;

//插入新结点
BiTNode *p = (BiTree) malloc (sizeof(BiTNode));
p -> data = {2};
p -> lchild = NULL;
p -> rchild = NULL;
root -> lchild = p; //作为根节点的左孩子


逆向寻找父节点

三叉链表
在这里插入图片描述

5.3二叉树的遍历和线索二叉树

5.3.1二叉树的遍历

在这里插入图片描述
在这里插入图片描述

1. 先序遍历(根左右 NLR)

若二叉树为空,不用操作

若二叉树非空:

  • 访问根节点
  • 先序遍历左子树
  • 先序遍历右子树
typedef struct BiTnode{
   ElemType data;          
   struct BiTNode *lchild, *rchild; 
}BiTNode, *BiTree;

void PreOrder(BiTree T){
   if(T!=NULL){
      visit(T);                 //访问根结点
      PreOrder(T->lchild);      //递归遍历左子树
      PreOrder(T->rchild);      //递归遍历右子树
   }
}


2. 中序遍历(左根右 LNR)

若二叉树为空,不用操作

若二叉树非空:

  • 先序遍历左子树
  • 访问根节点
  • 先序遍历右子树
typedef struct BiTnode{
   ElemType data;          
   struct BiTNode *lchild, *rchild; 
}BiTNode, *BiTree;

void InOrder(BiTree T){
   if(T!=NULL){
      InOrder(T->lchild);       //递归遍历左子树
      visit(T);                 //访问根结点
      InOrder(T->rchild);       //递归遍历右子树
   }
}


3. 后续遍历(左右根 LRN)

若二叉树为空,不用操作

若二叉树非空:

  • 先序遍历左子树
  • 先序遍历右子树
  • 访问根节点
typedef struct BiTnode{
   ElemType data;          
   struct BiTNode *lchild, *rchild; 
}BiTNode, *BiTree;

void PostOrder(BiTree T){
   if(T!=NULL){
      PostOrder(T->lchild);       //递归遍历左子树    
      PostOrder(T->rchild);       //递归遍历右子树
      visit(T);                 //访问根结点
   }
}

4. 求树的深度(递归应用)

在这里插入图片描述

5. 非递归遍历

  1. 先序遍历
    在这里插入图片描述
    在这里插入图片描述

  2. 中序遍历
    在这里插入图片描述

  3. 后序遍历
    在这里插入图片描述
    在这里插入图片描述

6. 层次遍历

在这里插入图片描述

//二叉树的结点(链式存储)
typedef struct BiTnode{
   ElemType data;          
   struct BiTNode *lchild, *rchild; 
}BiTNode, *BiTree;

//链式队列结点
typedef struct LinkNode{
   BiTNode * data;
   typedef LinkNode *next;
}LinkNode;

typedef struct{
   LinkNode *front, *rear;  
}LinkQueue;

//层序遍历
void LevelOrder(BiTree T){
   LinkQueue Q;
   InitQueue (Q);          //初始化辅助队列
   BiTree p;
   EnQueue(Q,T);           //将根节点入队
   while(!isEmpty(Q)){     //队列不空则循环
      DeQueue(Q,p);        //队头结点出队
      visit(p);            //访问出队结点
      if(p->lchild != NULL)
         EnQueue(Q,p->lchild);   //左孩子入队
      if(p->rchild != NULL)
         EnQueue(Q,p->rchild);   //右孩子入队
   }
}


7. 由遍历序列构造二叉树

给定的二叉树的遍历序列是固定的;给定遍历序列得到的二叉树是不固定的

  • 先序序列 + 中序序列
  • 后序序列 + 中序序列
  • 层序序列 + 中序序列

key: 找到树的根节点,并根据中序序列划分左右子树,再找到左右子树根节点
这也是为什么一定要有中序序列的原因
其他的遍历序列不能判断左子树和右子树的相对位置关系

5.3.2线索二叉树

从某个节点的前驱后继、遍历都很不方便
在这里插入图片描述

1. 线索二叉树的概念与作用

在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化。

2.线索二叉树的存储结构

在这里插入图片描述

  • 中序线索二叉树——线索指向中序前驱、中序后继
//线索二叉树结点
typedef struct ThreadNode{
   ElemType data;
   struct ThreadNode *lchild, *rchild;
   int ltag, rtag;                // 左、右线索标志
}ThreadNode, *ThreadTree;



  • 先序线索二叉树——线索指向先序前驱、先序后继

  • 后序线索二叉树——线索指向后序前驱、后序后继

3. 二叉树的线索化

在这里插入图片描述

全局变量pre

1. 中序线索化

typedef struct ThreadNode{
   int data;
   struct ThreadNode *lchild, *rchild;
   int ltag, rtag;                // 左、右线索标志
}ThreadNode, *ThreadTree;

//全局变量pre, 指向当前访问的结点的前驱
TreadNode *pre=NULL;

void InThread(ThreadTree T){
    if(T!=NULL){
        InThread(T->lchild);    //中序遍历左子树
        visit(T);               //访问根节点
        InThread(T->rchild);    //中序遍历右子树
    }
}

void visit(ThreadNode *q){
   if(q->lchid = NULL){                 //左子树为空,建立前驱线索   
      q->lchild = pre;
      q->ltag = 1;
   }

   if(pre!=NULL && pre->rchild = NULL){ 
      pre->rchild = q;           //建立前驱结点的后继线索
      pre->rtag = 1;
   }
   pre = q;
}

//中序线索化二叉树T
void CreateInThread(ThreadTree T){
   pre = NULL;                //pre初始为NULL
   if(T!=NULL);{              //非空二叉树才能进行线索化
      InThread(T);            //中序线索化二叉树
      if(pre->rchild == NULL)
         pre->rtag=1;         //处理遍历的最后一个结点
   }
}



2. 先序线索化

注意【转圈】问题,当ltag==0时,才能对左子树先序线索化

typedef struct ThreadNode{
   int data;
   struct ThreadNode *lchild, *rchild;
   int ltag, rtag;                // 左、右线索标志
}ThreadNode, *ThreadTree;

//全局变量pre, 指向当前访问的结点的前驱
TreadNode *pre=NULL;

//先序遍历二叉树,一边遍历一边线索化
void PreThread(ThreadTree T){
   if(T!=NULL){
      visit(T);
      if(T->ltag == 0)         //lchild不是前驱线索
      //并且由于中序和后序都已经处理完了左子树,所以用不到lchild
         PreThread(T->lchild);
      PreThread(T->rchild);
   }
}

void visit(ThreadNode *q){
   if(q->lchid = NULL){                 //左子树为空,建立前驱线索   
      q->lchild = pre;
      q->ltag = 1;
   }

   if(pre!=NULL && pre->rchild = NULL){ 
      pre->rchild = q;           //建立前驱结点的后继线索
      pre->rtag = 1;
   }
   pre = q;
}

//先序线索化二叉树T
void CreateInThread(ThreadTree T){
   pre = NULL;                //pre初始为NULL
   if(T!=NULL);{              //非空二叉树才能进行线索化
      PreThread(T);            //先序线索化二叉树
      if(pre->rchild == NULL)
         pre->rtag=1;         //处理遍历的最后一个结点
   }
}


3. 后序线索化

typedef struct ThreadNode{
   int data;
   struct ThreadNode *lchild, *rchild;
   int ltag, rtag;                // 左、右线索标志
}ThreadNode, *ThreadTree;

//全局变量pre, 指向当前访问的结点的前驱
TreadNode *pre=NULL;

//先序遍历二叉树,一边遍历一边线索化
void PostThread(ThreadTree T){
   if(T!=NULL){
      PostThread(T->lchild);
      PostThread(T->rchild);
      visit(T);                  //访问根节点
   }
}

void visit(ThreadNode *q){
   if(q->lchid = NULL){                 //左子树为空,建立前驱线索   
      q->lchild = pre;
      q->ltag = 1;
   }

   if(pre!=NULL && pre->rchild = NULL){ 
      pre->rchild = q;           //建立前驱结点的后继线索
      pre->rtag = 1;
   }
   pre = q;
}

//先序线索化二叉树T
void CreateInThread(ThreadTree T){
   pre = NULL;                //pre初始为NULL
   if(T!=NULL);{              //非空二叉树才能进行线索化
      PostThread(T);            //后序线索化二叉树
      if(pre->rchild == NULL)
         pre->rtag=1;         //处理遍历的最后一个结点
   }
}


中序和后序都已经处理完了左子树,所以用不到lchild,也就不同考虑他的转圈问题

4. 线索树的寻找前驱后继的各种情况(多理解)

在这里插入图片描述

5.4树、森林

在这里插入图片描述

5.4.1树的存储结构

1. 双亲表示法(顺序存储):

在这里插入图片描述

每个结点中保存指向双亲的指针
数据域:存放结点本身信息。
双亲域:指示本结点的双亲结点在数组中的位置。

#define MAX_TREE_SIZE 100  //树中最多结点数

typedef struct{      //树的结点定义
   ElemType data; 
   int parent;      //双亲位置域
}PTNode;

typedef struct{                   //树的类型定义
   PTNode nodes[MAX_TREE_SIZE];   //双亲表示
   int n;                         //结点数
}PTree;


基本操作:

  • 增:新增数据元素,无需按逻辑上的次序存储,只要在最后增加并且写上其父节点(需要更改结点数n)
  • 删(叶子结点):① 将伪指针域设置为-1;②用后面的数据填补(不会中间出现空数据);(需要更改结点数n)
  • 查询:①优点-查指定结点的双亲很方便;②缺点-查指定结点的孩子只能从头遍历,空数据导致遍历更慢;
  • 所以删除时用②用后面的数据填补(不会中间出现空数据);(需要更改结点数n)这个方法更好
  • 求双亲很方便,但是求结点的孩子需要遍历整个结构

2. 孩子表示法(顺序+链式)

孩子链表:把每个结点的孩子结点排列起来,看成是一个线性表,用单链表存储,则n个结点有n个孩子链表(叶子的孩子链表为空表)。而n个头结点又组成一个线性表,用顺序表(含n个元素的结构数组)存储
在这里插入图片描述
问题在于:找孩子方便,找双亲不方便,需要遍历整个结构(n个结点的孩子链表指针域指向的n个孩子链表)

struct CTNode{
   int child;    //孩子结点在数组中的位置
   struct CTNode *next;    // 下一个孩子
};

typedef struct{
   ElemType data;
   struct CTNode *firstChild;    // 第一个孩子
}CTBox;

typedef struct{
   CTBox nodes[MAX_TREE_SIZE];
   int n, r;   // 结点数和根的位置
}CTree;


3. 孩子兄弟表示法(链式)

第一个孩子与右兄弟
特点:

  1. 最大的优点是实现树转换成二叉树和相互转换
  2. 易于查找结点的孩子
  3. 缺点是从当前结点查找双亲很麻烦,可以为每个结点设置一个parent指针指向父结点
  4. 孩子表示法存储的树,在物理上是二叉树

在这里插入图片描述

typedef struct CSNode{
   ElemType data;                               //数据域
   struct CSNode *firstchild, *nextsibling;     //第一个孩子和右兄弟指针, *firstchild 看作左指针,*nextsibling看作右指针
}CSNode. *CSTree;


5.4.2树、森林与二叉树的转换

本质:森林中各个树的根结点之间视为兄弟关系

在这里插入图片描述
在这里插入图片描述

5.4.3树、森林的遍历

在这里插入图片描述
在这里插入图片描述

1. 树的遍历

先根后根都是深度优先,层次是广度优先遍历

先根遍历

  • 若树非空,先访问根结点,再依次对每棵子树进行先根遍历;(与对应二叉树的先序遍历序列相同树的深度优先遍历
void PreOrder(TreeNode *R){
   if(R!=NULL){
      visit(R);    //访问根节点
      while(R还有下一个子树T)
         PreOrder(T);      //先跟遍历下一个子树
   }
}


在这里插入图片描述

后根遍历

树的深度优先遍历

  • 若树非空,先依次对每棵子树进行后根遍历,最后再返回根节点;(与对应二叉树的中序遍历序列相同但是直接看的话还是后序遍历序列,不转化成二叉树来看的话就直接用后序遍历求解

在这里插入图片描述

void PostOrder(TreeNode *R){
   if(R!=NULL){
      while(R还有下一个子树T)
         PostOrder(T);      //后跟遍历下一个子树
      visit(R);    //访问根节点
   }
}


层序遍历(队列实现)

广度优先遍历

若树非空,则根结点入队;
若队列非空,队头元素出队并访问,同时将该元素的孩子依次入队;
重复以上操作直至队尾为空;

2. 森林的遍历

先序遍历:等同于依次对各个树进行先根遍历;也可以先转换成与之对应的二叉树,对二叉树进行先序遍历;
中序遍历:等同于依次对各个树进行后根遍历;也可以先转换成与之对应的二叉树,对二叉树进行中序遍历;

5.5树与二叉树的应用

5.5.1 哈夫曼树和哈夫曼编码

1. 带权路径长度的定义

权值大于零
在这里插入图片描述

2. 哈夫曼树的定义(最优二叉树,不唯一)

在这里插入图片描述

3. 哈夫曼树的构造

每次都选取权值最小的结点构成一棵树,并且新的树的根节点的权值为两个子结点的权值之和,重复这个步骤就能构成哈夫曼树
在这里插入图片描述

4. 哈夫曼树的特点

叶子结点n,度为二的结点n-1
在这里插入图片描述

5.哈夫曼编码(最短二进制前缀编码)

  • 固定长度编码
    在这里插入图片描述
  • 可变长度编码(无歧义)

在这里插入图片描述

5.5.2 并查集(双亲表示法)

1. 并查集的存储结构

在这里插入图片描述
在这里插入图片描述

2. 并查集的代码实现

初始化

在这里插入图片描述

并查

在这里插入图片描述

时间复杂度

在这里插入图片描述

union操作的优化(不要瘦高的树)

在这里插入图片描述
在这里插入图片描述

并查集的进一步优化(find的优化,压缩路径)

在这里插入图片描述
在这里插入图片描述

优化总结

在这里插入图片描述
在这里插入图片描述

5.5.3二叉排序树(BST)

1. 二叉排序树的定义

左子树结点值<根结点值<右子树结点值

2. 查找操作

typedef struct BSTNode{
   int key;
   struct BSTNode *lchild, *rchild;
}BSTNode, *BSTree;

//在二叉排序树中查找值为key的结点(非递归)
//最坏空间复杂度:O(1)
BSTNode *BST_Search(BSTree T, int key){
   while(T!=NULL && key!=T->key){        //若树空或等于跟结点值,则结束循环
      if(key<T->key)       //值小于根结点值,在左子树上查找
         T = T->lchild;
      else                  //值大于根结点值,在右子树上查找
         T = T->rchild;
   }
   return T;
}

//在二叉排序树中查找值为key的结点(递归)
//最坏空间复杂度:O(h)
BSTNode *BSTSearch(BSTree T, int key){
   if(T == NULL)
      return NULL;
   if(Kry == T->key)
      return T;
   else if(key < T->key)
      return BSTSearch(T->lchild, key);
   else 
      return BSTSearch(T->rchild, key);
}


3. 插入操作

//在二叉排序树中插入关键字为k的新结点(递归)
//最坏空间复杂度:O(h)
int BST_Insert(BSTree &T, int k){
   if(T==NULL){           //原树为空,新插入的结点为根结点
      T = (BSTree)malloc(sizeof(BSTNode));
      T->key = k;
      T->lchild = T->rchild = NULL;
      return 1;                       //插入成功
   }
   else if(K == T->key)               //树中存在相同关键字的结点,插入失败
      return 0;
   else if(k < T->key)                 
      return BST_Insert(T->lchild,k);
   else 
      return BST_Insert(T->rchild,k);
}


4. 二叉排序树的构造

//按照str[]中的关键字序列建立二叉排序树
void Crear_BST(BSTree &T, int str[], int n){
   T = NULL;                     //初始时T为空树
   int i=0;
   while(i<n){
      BST_Insert(T,str[i]);     //依次将每个关键字插入到二叉排序树中
      i++;
   }
}


在这里插入图片描述

5.5.2平衡二叉树(AVL)

  1. 平衡二叉树的定义
    在插入和删除二叉树的结点时,要保证任意结点的左右子树的高度差的绝对值不超过1,将这样的树称为平衡二叉树。
//平衡二叉树结点
typedef struct AVLNode{
   int key;         //数据域
   int balance;     //平衡因子
   struct AVLNode *lchild; *rchild; 
}AVLNode, *AVLTree;



在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/62227.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Paper】2020_网络化多智能体系统的事件触发一致性研究_徐勇

徐勇. 网络化多智能体系统的事件触发一致性研究[D].浙江大学,2020.DOI:10.27461/d.cnki.gzjdx.2020.001385. 文章目录 5 已知 DoS 攻击策略下多智能体系统的事件触发安全一致性分析5.1 引言5.2 数学模型与问题描述5.3 控制器和事件触发条件的设计5.5 数值仿真程序 Main.m程序 M…

使用FreeMarker导出word文档(支持导出图片)

今天跟大家分享一下工作中比较实用的导出word 带图片的功能。 对于在idea开发中我们需要引入以下依赖&#xff1a; 2.对于eclipse 开发我们需要进入对应的jar包 这个必须放在lib下&#xff0c;同样也需要在当前项目的环境是加入该依赖 需要在MEAT-INF加入 首先制定word 导出…

UE5 半透明覆层材质

文章目录 前言介绍示例1示例2示例3 前言 本文采用虚幻5.2.1版本演示&#xff0c;介绍半透明覆层材质&#xff08;覆层材质&#xff09;。 介绍 半透明覆层材质是 UE5.1 版本 更新的功能&#xff0c;使用半透明覆层材质&#xff0c;可以轻松的给物体表面附着一层材质。 在UE5…

Python3 处理PDF之PyMuPDF 入门

PyMuPDF 简介 PyMuPDF是一个用于处理PDF文件的Python库&#xff0c;它提供了丰富的功能来操作、分析和转换PDF文档。这个库的设计目标是提供一个简单易用的API,使得开发者能够轻松地在Python程序中实现PDF文件的各种操作。 PyMuPDF的主要特点如下&#xff1a; 跨平台兼容性&a…

Aspose.Imaging for Python via .NET Crack

Aspose.Imaging for Python via .NET Crack Aspose.Imaging for Python via.NET是一个提供高级图像处理功能的库。您可以使用此API轻松创建、加载、操作、转换或压缩图像。另外&#xff0c;Aspose.Imaging for Python通过.NET支持绘图和使用图形基元。图像导出和转换-API的核心…

SpringCloud(29):Nacos简介

1 什么是配置中心 1.1 什么是配置 应用程序在启动和运行的时候往往需要读取一些配置信息&#xff0c;配置基本上伴随着应用程序的整个生命周期&#xff0c;比如&#xff1a;数据库连接参数、启动参数等。 配置主要有以下几个特点&#xff1a; 配置是独立于程序的只读变量 …

编译LightGBM错误处理记录

在LightGBM源码中新建文件夹build&#xff0c;然后在build目录下运行命令 cmake -A x64 -DUSE_GPU1 -DBOOST_ROOTC:\local\boost_1_82_0 -DBOOST_LIBRARYDIRC:\local\boost_1_82_0\lib64-msvc-14.3 .. 报错 错误原因&#xff1a; miniconda3\Library\lib\cmake\中boost版本是…

状态模式(State)

状态模式是一种行为设计模式&#xff0c;允许一个对象在其内部状态改变时改变它的行为&#xff0c;使其看起来修改了自身所属的类。其别名为状态对象(Objects for States)。 State is a behavior design pattern that allows an object to change its behavior when its inter…

前端个人年度工作述职报告(二十篇)

前端个人年度工作述职报告篇1 尊敬的各位领导、各位同仁&#xff1a; 大家好!按照20__年度我公司就职人员工作评估的安排和要求&#xff0c;我认真剖析、总结了自己的工作情况&#xff0c;现将本人工作开展情况向各位领导、同仁做以汇报&#xff0c;有不妥之处&#xff0c;希…

【前瞻】视频技术的发展趋势讨论以及应用场景

视频技术的发展可以追溯到19世纪初期的早期实验。到20世纪初期&#xff0c;电视技术的发明和普及促进了视频技术的进一步发展。 1&#xff09;数字化&#xff1a;数字化技术的发明和发展使得视频技术更加先进。数字电视信号具有更高的清晰度和更大的带宽&#xff0c;可以更快地…

ospf减少LSA更新

实验及实验要求 一、思路 1.根据区域划分IP地址 2.使公网可通---写缺省 3.使R3成为MGRE中心站点&#xff0c;R5、R6、R7为分支站点 4.一个个去配置ospf区域和RIP区域&#xff0c;确保每个区域配置无误 5.区域0要更改OSPF在接口的工作类型为broadcast &#xff0c;并使R3为…

【C++】容器篇(五)—— map和set的基本介绍

序言&#xff1a; 在之前&#xff0c;我们已经对STL中的 序列式容器 进行了相关的学习。本期&#xff0c;我将给大家介绍的则是另外一类容器 —— 关联式容器 &#xff01;&#xff01;&#xff01; 目录 &#xff08;一&#xff09;容器回顾 &#x1f4a8;【顺序容器】 &a…

【二进制安全】堆漏洞:Double Free原理

参考&#xff1a;https://www.anquanke.com/post/id/241598 次要参考&#xff1a;https://xz.aliyun.com/t/6342 malloc_chunk 的源码如下&#xff1a; struct malloc_chunk { INTERNAL_SIZE_T prev_size; /*前一个chunk的大小*/ INTERNAL_SIZE_T size; /*当前chunk的…

无涯教程-Perl - binmode函数

描述 此函数设置在区分两者的操作系统上以二进制形式读取和写入FILEHANDLE的格式。非二进制文件的CR LF序列在输入时转换为LF,在LF时在输出时转换为CR LF。这对于使用两个字符分隔文本文件中的行的操作系统(MS-DOS)至关重要,但对使用单个字符的操作系统(Unix,Mac OS,QNX)没有影…

C#中XML文档与Treeview控件操作的数据同步

在前文《C#使用XML和Treeview结合实现复杂数据采集功能》中&#xff0c;使用Treeview展示了XML的数据&#xff0c;问题是如果在Treeview上进行了操作&#xff0c;怎样同步更改XML数据的内容呢&#xff1f; 这个问题看似简单&#xff0c;实现起来有一点小麻烦。 要实现的操作功能…

6.s081/6.1810(Fall 2022)Lab2: System calls

文章目录 前言其他篇章参考链接0. 前置准备1. System call tracing (moderate)1.1 简单分析1.2 Hint 11.3 Hint 21.4 Hint 31.5 Hint 41.6 Hint 51.7 测试 2. Sysinfo (moderate)2.1 声明2.2 实现2.2.1 框架2.2.2 用户态与内核态交互2.2.3 计算空闲内存的大小2.2.4 计算非UNUSE…

postgresql表膨胀处理之pgcompacttable部署及使用

环境&#xff1a; 1&#xff09;redhat-release&#xff1a;CentOS Linux release 7.6.1810 (Core) 2&#xff09;database version&#xff1a;postgresql 14.6 一、添加pgstattuple pgcompacttable工具使用过程中需要依赖pgstattuple&#xff0c;因此需先添加pgstattuple…

工业控制系统安全控制应用指南

工业控制系统安全控制应用 指南 工业控制系统&#xff08;ICS&#xff09;&#xff08;包括监控和数据采集系统&#xff08;SCADA&#xff09;、分布式控制系统(DCS)、可编程逻辑控制器(PLC)等产品&#xff09;在核设施、航空航天、先进制造、石油石化、油气管网、电力系统、交…

Qt应用开发(基础篇)——时间类 QDateTime、QDate、QTime

一、前言 时间类QDateTime、QDate、QTime、QTimeZone保存了Qt的时间、日期、时区信息&#xff0c;常用的时间类部件都会用到这些数据结构&#xff0c;常用概念有年、月、日、时、分、秒、毫秒和时区&#xff0c;时间和时区就关系到时间戳和UTC的概念。 UTC时间&#xff0c;又称…

K8s中的核心技术Helm

1.helm的引入 &#xff08;1&#xff09;编写yaml文件 &#xff08;2&#xff09;编写deployment文件 &#xff08;3&#xff09;编写service文件 &#xff08;4&#xff09;编写Ingress文件 2.helm的引入解决的问题&#xff1f; &#xff08;1&#xff09;使用helm可以把…