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)——从上往下
- 结点的高度——从下往上
- 树的高度——总共多少层
- 结点的度——有几个孩子
- 树的度——各结点的度的最大值
有序树(家谱,从左到右有次序不可以互换)、无序树(左右位置没有逻辑关系,可以互换)
森林(多颗互不相交的树的集合,允许有空森林,跟树一样节点数可以为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 几种特殊的二叉树
-
满二叉树:一颗深度为k且有2^k-1个结点的二叉树称为满二叉树。每一层上的结点数都达到最大。叶子全部在最低层。
-
完全二叉树:深度为k的具有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号为1~n的结点一 一对应时,称之为完全二叉树。(缺少的只会是最后一个节点,递归这种缺少才能满足,就是不能缺少8号节点,因为这样8后边的所有节点都会变换序号,与满二叉树不一样了)
完全二叉树的最多且唯一一个度为1的节点一定有的是左孩子 -
二叉排序树
-
平衡二叉树
5.2.3 二叉树的性质
5.2.4 完全二叉树的性质
5.2.5 二叉树的存储结构
1. 顺序存储
#define MaxSize 100struct 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. 非递归遍历
-
先序遍历
-
中序遍历
-
后序遍历
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初始为NULLif(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不是前驱线索//并且由于中序和后序都已经处理完了左子树,所以用不到lchildPreThread(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初始为NULLif(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初始为NULLif(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. 孩子兄弟表示法(链式)
第一个孩子与右兄弟
特点:
- 最大的优点是实现树转换成二叉树和相互转换
- 易于查找结点的孩子
- 缺点是从当前结点查找双亲很麻烦,可以为每个结点设置一个parent指针指向父结点
- 孩子表示法存储的树,在物理上是二叉树
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,将这样的树称为平衡二叉树。
//平衡二叉树结点
typedef struct AVLNode{int key; //数据域int balance; //平衡因子struct AVLNode *lchild; *rchild;
}AVLNode, *AVLTree;
相关文章:

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. 链式存储逆向…...

构建稳健的微服务架构:关键的微服务设计原则和最佳实践
在现代软件开发中,微服务架构正逐渐成为构建复杂应用程序的首选方法之一。微服务架构的核心理念是将应用程序划分为一系列小型、自治的服务,每个服务专注于一个特定的业务功能。然而,要实现一个稳健的微服务架构并不仅仅是将功能拆分成微服务…...

消息队列常见问题(1)-如何保障不丢消息
目录 1. 为什么消息队列会丢消息? 2. 怎么保障消息可靠传递? 2.1 生产者不丢消息 2.2 服务端不丢消息 2.3 消费者不丢消息 3. 消息丢失如何快速止损? 3.1 完善监控 3.2 完善止损工具 1. 为什么消息队列会丢消息? 现在主流…...

Circle of Mistery 2023牛客暑期多校训练营5 B
登录—专业IT笔试面试备考平台_牛客网 题目大意:给出一个n个数的数组a,求一个排列,使其形成的其中一个置换环上的数的和>k,并使产生的逆序对数量最少 1<n<1e3;-1e6<k<1e6;-1e6<ai<1e6 tips:关于置换环是什…...

VC9、VC10、VC11等等各对应什么版本的Visual Studio,以及含义
文章目录 1、_MSC_VER 定义编译器的版本2、示例 1、_MSC_VER 定义编译器的版本 MS VC 15.0 _MSC_VER 1910 (Visual Studio 2017) MS VC 14.0 _MSC_VER 1900 (Visual Studio 2015) MS VC 12.0 _MSC_VER 1800 (VisualStudio 2013) MS VC 11.0 _MSC_VER 1700 (VisualStudio…...

两数相加 LeetCode热题100
题目 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会…...

Python基础 P2数字类型与优先级进阶练习
文章目录 Python基础 P2数字类型与优先级进阶练习1.闰年判断器2.进制转换及求和3.单位转换 Python基础 P2数字类型与优先级进阶练习 1.闰年判断器 简介 对于闰年的判断就是判断输入的内容类型是否符合要求,然后通过逻辑判断和运算得出该年份是否为闰年 举个栗子 …...

CAPL通过继电器实现CAN容错性自动化测试
系列文章目录 文章目录 系列文章目录前言一、环境搭建1.硬件环境2.软件环境3.继电器线路连接图:二、容错性测试方法1.CAN_H与CAN_L短路2.CAN_H与GND短路3.CAN_L与GND短路4.CAN_H与电源短路5.CAN_L与电源短路6.CAN_H断路7.CAN_L断路三、CAPL自动化测试1.测试用例目录2.测试报告…...

elasticsearch 配置用户名和密码
无密码的其他配置项在:https://blog.csdn.net/Xeon_CC/article/details/132064295 elasticsearch.yml配置文件: xpack.security.enabled: true xpack.security.http.ssl.enabled: true xpack.security.http.ssl.keystore.path: /path/to/elastic-certi…...

侯捷 C++面向对象编程笔记——9 复合 委托
9 复合 委托 9.1 Composition 复合 类似于c中结构里有结构——class里有class deque 是一个已经存在的功能很多的类(两头进出的队列);利用deque的功能来实现queue的多种操作 该例只是复合的一种情况——设计模式 Adapter 9.1.1 复合下的构造…...

状态模式——对象状态及其转换
1、简介 1.1、概述 在软件系统中,有些对象也像水一样具有多种状态,这些状态在某些情况下能够相互转换,而且对象在不同的状态下也将具有不同的行为。为了更好地对这些具有多种状态的对象进行设计,可以使用一种被称为状态模式的设…...

Linux一阶段复习
Linux之父是林纳斯本纳第克特托瓦兹 Apache发布目录:/var/www/html nginx发布目录:/usr/share/nginx/html/ 配置dns的文件 : /etc/resolv.conf nginx的配置文件:/etc/nginx/ yum源的配置文件:/etc/yum.repos.d/ …...

宝塔Linux面板怎么升级?升级命令及失败解决方法
宝塔Linux面板怎么升级到新版本?root账号ssh登录到云服务器后,执行宝塔Linux面板升级命令即可搞定,新手站长分享宝塔Linux面板升级命令: 宝塔面板升级到新版本 1、使用root账号ssh登录到云服务器上 ssh root你的云服务器ip地址…...

前端面试的性能优化部分(6)每天10个小知识点
目录 系列文章目录前端面试的性能优化部分(1)每天10个小知识点前端面试的性能优化部分(2)每天10个小知识点前端面试的性能优化部分(3)每天10个小知识点前端面试的性能优化部分(4)每天…...

2023年 Java 面试八股文(20w字)
目录 第一章-Java基础篇 1、你是怎样理解OOP面向对象 难度系数:⭐ 2、重载与重写区别 难度系数:⭐ 3、接口与抽象类的区别 难度系数:⭐ 4、深拷贝与浅拷贝的理解 难度系数:⭐ 5、sleep和wait区别 难度系数&a…...

银河麒麟服务器ky10-server在线一键安装docker
脚本代码 # ---------------在线安装docker------------------- yum install docker -y # 修改docker拉取源为国内 rm -rf /etc/docker mkdir -p /etc/docker touch /etc/docker/daemon.json cat >/etc/docker/daemon.json<<EOF{"registry-mirrors": [&q…...

spring boot中web容器配置
web容器配置 spring boot 默认的web容器是 tomcat,如果需要换成其他的 web 容器,可以如下配置。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 默…...

DNSlog注入(利用DNSlog平台将SQL盲注变成回显注入)
前言什么是UNC什么是DNSlog注入DNSlog注入的条件防止DNSlog注入的几个措施 sqli-labs试验 前言 前几天面试的时候,面试官问我知不知道OOB(带外数据)。 当时我蒙了,确实没听说过这个东西,然后面试官告诉我原来dnslog注入…...

vim学习笔记(致敬vim作者)
vim cheat sheet 30. vim 删除大法 vim 删除某个字符之后改行的其他的字符?删除某行之后的其他行?删除某个字符之后的其他字符?【1】删除单个字符? 跳到要删除的字符位置 按下d键然后按下shift 4键 【2】删除某行之后的其他行…...

力扣 -- 139. 单词拆分
一、题目 题目链接:139. 单词拆分 - 力扣(LeetCode) 二、解题步骤 下面是用动态规划的思想解决这道题的过程,相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴。 三、参考代码 class Solution { public:bool wordBreak(str…...
百度秋招攻略,百度网申笔试面试详解
百度秋招简介 作为行业巨头,百度向社会提供的岗位一直都是非常吃香的,每年也都有很多考生密切关注,百度发布的招聘广告,以尽可能的让自己进入这家企业工作,实现自己的人生价值。那么百度每年的秋招时间是多久…...

nohup Java -jar 生成的nohup.out 文件一直增加,如何处理
目录 1 实现 1 实现 除了使用echo "" > filename清空文件内容之外,还有其他几种方法可以删除文件中的内容而不删除文件本身:使用truncate命令:truncate命令可以用来截断文件并清空内容。使用以下命令清空文件内容:t…...

静态页面与动态页面的区别及部署jpress应用
简述静态网页和动态网页的区别 静态网页: 1、首先是静态网页,静态网页每个网页中都有一个固定的URL,网页URL以htm、HTML、jpg、.gif、.mp4等常见形式为后缀,而且不含有问号; 2、静态网页内容一经发布到网页服务器上…...

华为数通HCIA-华为VRP系统基础
什么是VRP? VRP是华为公司数据通信产品的通用操作系统平台,作为华为公司从低端到核心的全系列路由器、以太网交换机、业务网关等产品的软件核心引擎。 VRP提供以下功能: 实现统一的用户界面和管理界面 实现控制平面功能,并定义转发平面接口…...

基于Azure OpenAI Service 的知识库搭建实验⼿册
1.概要 介绍如何使⽤Azure OpenAI Service 的嵌⼊技术,创建知识库;以及创建必要的资源组和资源,包括 Form Recognizer 资源和 Azure 翻译器资源。在创建问答机器⼈服务时,需要使⽤已部署模型的 Azure OpenAI 资源、已存在的…...

第七节--结构体
lesson19: 一、结构的基础知识 1.数组是一组xx集合(1:10:10) 2.结构体是XX的集合(1:10:25) 二、结构的声明(看课件)(1:12…...

Docker学习(二十四)报错速查手册
目录 一、This error may indicate that the docker daemon is not running 报错docker login 报错截图:原因分析:解决方案: 二、Get "https://harbor.xxx.cn/v2/": EOF 报错docker login 报错截图:原因分析:…...

一种SpringBoot下Scheduler定时任务优雅退出方案
背景 近期业务中有一个定时任务发现每次服务部署时,偶发性的会触发问题,这里记录一下问题的跟进解决。 分析现象 该定时任务每2分钟执行一次,完成数据的更新处理。同时服务部署了多个服务器节点,为保证每次只有一个服务器节点上…...

DNS部署与安全详解(上)
文章目录 一、DNS二、域名组成1. 域名组成概述2. 域名组成 三、监听端口四、DNS解析种类1. 按照查询方式分类:2. 按照查询内容分类: 五、DNS服务器搭建过程1. 先确保服务器的IP地址是固定的2. 安装DNS软件 一、DNS DNS全称Domain Name Service࿰…...

【51单片机】晨启科技,酷黑版,音乐播放器
四、音乐播放器 任务要求: 设计制作一个简易音乐播放器(通过手柄板上的蜂鸣器发声,播放2到4首音乐),同时LED模块闪烁,给人视、听觉美的感受。 评分细则: 按下播放按键A6开始播放音乐࿰…...