数据结构(C语言)-树

article/2025/8/19 6:20:47

  • 一、树
    • 1、树的定义
    • 2、树的基本术语
    • 3、树结构和线性结构的比较
  • 二、二叉树
    • 1、二叉树的定义
    • 2、二叉树的形态与树的形态
    • 3、二叉树的性质
    • 4 、二叉树的存储结构
    • 5、遍历二叉树
    • 6、二叉树的其他操作
    • 7、线索二叉树
  • 三、树与二叉树的转换
    • 1、树转换成二叉树
    • 2、二叉树变树
  • 四、哈夫曼树
    • 1、相关概率与定义
    • 2、哈夫曼树的构造与算法
    • 3、哈夫曼编码

学习视频

一、树

1、树的定义

(1)树的定义
树(Tree)n(n>=0)个有限数据元素的集合。当n=0时称为空树。当n>0时,是非空树,它满足以下两个条件:
- 有且仅有一个特定的称为根(Root)的结点;
- 其余结点可分为m (m≥0)个互不相交的有限集T1,T2,T3,…Tm,其中每一个集合本身又是一棵树,并称为根的子树(SubTree)。
(2)树的表示方法
树的逻辑结构表示主要有四种:树形表示法,嵌套集合表示法,凹入表示法和广义表表示法等
在这里插入图片描述
在这里插入图片描述

2、树的基本术语

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

  • 森林:是m(mzO)棵互不相交的树的集合。把根结点删除树就变成了森林。一棵树可以看成是一个特殊的森林。给森林中的各子树加上一个双亲结点,森林就变成了树。树一定是森林,森林不一定是树。
  • 有序树:树中结点的各子树从左至右有次序(最左边的为第一个孩子)。无序树:树中结点的各子树无次序。

3、树结构和线性结构的比较

线性结构树结构
第一个数据元素无前驱根结点(只有一个)无双亲
最后一个数据元素无后继叶子结点(可以有多个)无孩子
其它数据元素其它结点—中间结点
一个前驱,一个后继一个双亲,多个孩子
一对一一对多

二、二叉树

1、二叉树的定义

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

  • 1、每个结点最多有俩孩子(二叉树中不存在度大于2的结点)。
  • 2、子树有左右之分,其次序不能颠倒。
  • 3、二叉树可以是空集合,根订以有空的左子树或空的右子树。

*注意:*二叉树不是树的特殊情况,它们是两个概率

  • 二叉树结点的子树要区分左子树和右子树,即使只有一棵子树也行区分,说明它是左子树,还是右子树。
  • 二叉树结点的子树要区分左子树和右子树,即使只有一棵子树也行区分,说明它是左子树,还是右子树。
    在这里插入图片描述在这里插入图片描述
  • 也就是二叉树每个结点位置或者说次序都是固定的,可以是空,但是不可以说它没有位置,而树的结点位置是相对于别的结点来说的,没有别的结点时,它就无所谓左右了
    在这里插入图片描述

2、二叉树的形态与树的形态

在这里插入图片描述
在这里插入图片描述
案例︰利用二叉树求解表达式的值以二叉树表示表达式的递归定义如下:

  • 若表达式为数或简单变量,则相应二叉树中仅有一个根结点,其数据域存放该表达式信息;
  • 若表达式为“第一操作数运算符第二操作数”的形式,则相应的二叉树中以左子树表示第一操作数,右子树表示第二操作数,根结点的数据域存放运算符(若为一元运算符,则左子树为空),其中,操作数本身又为表达式。
    在这里插入图片描述

3、二叉树的性质

(1)性质1:在二叉树的第i层上至多有2^(i-1)个结点(i≥1)。
在这里插入图片描述
第1层:2^0=1
第2层: 2^1=2
第3层:2^2=4
第4层:2^3=8
证:采用归纳法证明此性质。
归纳基:当i=1时,只有一个根结点,2^(i-1)=2*0 =1,命题成立。归纳假设:设对所有的j(1≤j<i),命题成立,
即第j层上至多7有2^(j-1)个结点。那么可以证明j=i时命题也成立。
归纳证明:由归纳假设可知,第i-1层上至多有2^(i-2)个结点。
由于二叉树每个结点的度最大为2,故在第i层上最大结点数为第i-1层上最大结点数的2倍,即:2x2^(i-2)=2的(i-1)次方 证毕。
(2)性质2:深度为k的二叉树至多有2^k-1个结点(k≥1)。
证:由性质1可知,深度为k的二叉树的最大结点数为:
在这里插入图片描述
(3)性质3:对任何一棵二叉树T,如果其叶子数为n0,度为2的结点数为n,则n0 = n2+ 1。
在这里插入图片描述
总边数为B B = n-1=B=n2×2+n1×1
总结点数为n n=n2×2+ n1x1+1又n = n2+ n 1+n0
(4)满二叉树
一棵深度为k且有2^k-1个结点的二叉树称为满二叉树。
特点:

  • 每一层上的结点数都是最大结点数(即每层都满),
  • 叶子节点全部在最底层
    对满二叉树结点位置进行编号:
  • 编号规则:从根结点开始,自上而下,自左而右。
  • 每一结点位置都有元素。
    在这里插入图片描述

例1:思考:下图中的二叉树是满二叉树吗?
在这里插入图片描述
答:不是满二叉树,叶子不在同一层上。且最后一层结点个数不满!
满二叉树在同样深度的二叉树中结点个数最多
满二叉树在同样深度的二叉树中叶子结点个数最多
(5)完全二叉树
深度为k的具有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号为1~n的结点—一对应时,称之为完全二叉树。
在这里插入图片描述
:在满二叉树中,从最后一个结点开始,连续去掉任意个结点,即是一棵完全二叉树.一定是连续的去掉!!!

例2:思考:左边的树是否是完全二叉树?
在这里插入图片描述

答:不是,I与J两结点不连续。
特点:

  • 叶子只可能分布在层次最天的两层上。
  • 对任一结点,如果其右子树的最大层次为i,则其左子树的最大层次必为i或i+1。
    (6)性质4具有n个结点的完全二叉树的深度为在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
(7)性质5:如果对一颗有n个结点的完全二叉树的结点按层次有:
在这里插入图片描述

4 、二叉树的存储结构

(1)顺序存储结构
顺序存储一颗二叉树,先对该二叉树中的各结点进行编号,然后以各结点的编号为下标,把各结点的值存到一维数组中
在这里插入图片描述
在这里插入图片描述
例3:二叉树结点数值采用顺序存储结构,如图所示。画出二叉树表示:
在这里插入图片描述
(2)链式存储结构

  • 二叉链表
typedef struct BiNode{TElemType data;struct BiNode *Ichild,*rchild;//左右孩子指针}BiNode,*BiTree;

例4:
在这里插入图片描述

  • 三叉链表
typedef struct TriTNode{TelemType data;struct TriTNode *lchild,*parent,*rchild;
}TriTNode,*TriTree;

在这里插入图片描述

5、遍历二叉树

(1)遍历二叉树

  • 遍历定义:顺着某一条搜索路径巡访二叉树中的结点,使得每个结点被访问一次,而且仅被访问一次(周游)。
    注意:“访问”的含义很广,可以是对结点作各种处理,如:输出结点的信息、修改结点数值等,但要求各种访问不破坏原来的数据结构。
  • 遍历目的:得到树中所有结点的一个线性排列。
  • 遍历用途:它是树结构插入、删除、修改、查找和排序运算的前提,是二叉树一切运算的基础核心。
    在这里插入图片描述
  • 先序遍历(DLR)
    若二叉树为空,则空操作;否则
    访问根结点;
    先序遍历左子树
    先序遍历右子树
    如图
    在这里插入图片描述在这里插入图片描述
  • 先序遍历的算法实现
//先序遍历的算法实现(DLR)
void PreOrder(BT *T){if(T==NULL) return;//递归调用结束条件 else{printf("%c",T->data);//输出根结点 PreOrder(T->lchild);//先序遍历左子树 PreOrder(T->rchild);//先序遍历右子树 }
} 
  • 中序遍历(LDR)
    若二叉树为空,则空操作;否则
    中序遍历左子树
    访问根结点
    中序遍历右子树
    如图:
    在这里插入图片描述在这里插入图片描述
  • 中序遍历的算法实现
//中序遍历的算法实现(LDR)
void InOrder(Bt *T){if(T==NULL) return;//递归调用结束条件 else{InOrder(T->lchild);//中序遍历左子树 printf("%c",T->data);//输出根结点 InOrder(T->rchild);//中序遍历右子树 }
} 
  • 后序遍历(LRD)
    若二叉树为空,则空操作;否则
    后序遍历左子树
    后序遍历右子树
    访问根结点
    如图:
    在这里插入图片描述在这里插入图片描述
  • 后序遍历的算法实现
//后序遍历的算法实现(LRD)
void PostOrder(BT *T){if(T==NULL) return;//递归调用结束条件 else{PostOrder(T->lchild);//后序遍历左子树 PostOrder(T->rchild);//后序遍历右子树 printf("%c",T->data);//输出根结点 }
} 
  • 层次遍历
    在这里插入图片描述
    对于一颗二叉树,从根结点开始,按从上到下、从左到右的顺序访问每个结点每个结点只能被访问一次。
  • 层次遍历的算法实现
//层次遍历的算法实现
void LevelOrder(BT *T){int f ,r;//定义队头指针 BT *p,*q[MAX];//定义循环队列,存放结点指针 p=T;if(p!=NULL){//若二叉树非空,则根结点地址入队 f=l;q[f]=p;r=2;}while(f!=r){//队列不为空 p=q[f];printf("%c",p->data);//访问队首结点 if(p->lchild!=NULL){q[r]=p->lchild;r=(r+1)%MAX;//将队首结点的左孩子入队 }if(p-<rchlid!=NULL){q[r]=p->rchlid;r=(r+1)%MAX;//将队首结点的右孩子入队 }f=(f+1)%MAX;}
} 

例5:写出下图二叉树的各种遍历顺序
在这里插入图片描述

解:先序:ABDGCEHF;中序:DGBAEHCF;后序:GDBHEFCA

例6:用二叉树表示算术表达式,请写出下图所示二叉树的先序、中序和后序遍历顺序
在这里插入图片描述
解:先序:-+axb-cd/ef;中序:a+bxc-d-e/f;后序:abcd-x+ef/-
(2)恢复二叉树
例7:已知先序和中序序列求二叉树

  • 已知二叉树的先序和中序序列,构造相对应的二叉树
    先序:ABCDEFGHIJ
    中序:CDBFEAIHGJ
    分析:由先序序列确定根结点;由中序序列确定左右子树
    解:由先序知根为A,则由中序知左子树为CDBFE,右子树为IHGJ
    在由先序得B为A的左孩子,因为现在得到的右子树为IHGJ,由先序遍历的规则知:G为A的右孩子,在由中序得CD为B得左子树,FE为B的右子树;IH为G左子树,J为G的右子树。因为 中序CDB先序BCD必定得C为B的左孩子D为C的右孩子,又因为先序EF中序FE得 ,E必然是B的右孩子,F为E的左孩子,
    在由先序GHI与中序IHG得H为G的左子树,I为H的左子树,即得如图的二叉树:
    在这里插入图片描述
  • 已知一颗二叉树的中序为:BDCEAFHG;后序为:DECBHGFA请画出这颗二叉树:
    解:由后序遍历得 A必然为根,因为中序为BDCEAFHG得A的左子树为BDCE右子树为FHG,在由后序DECBHGF得B必然为A的左孩子,F必然为A的右孩子,因为中序BDCE,后序DECB得C为B的右子孩子B没有左孩子,D为C的左孩子,E为C的右孩子。在因为中序FHG和后序HGF,F必然没有左子树 得 G必然为H的根H为G的左孩子得如图:
    在这里插入图片描述

6、二叉树的其他操作

(1)建立二叉树

BT *CreateBTree(){BT *t;char ch;scanf("%c",&ch);getchar();if(ch=='0'){t=NULL;	}else{t=(Bt*)malloc(sizeof(BT));t->data=ch;printf("请输入%c结点的左孩子结点:",t->data);t->lchild=CreateBtree();printf("请输入%c结点的右孩子结点:",t->data);t->rchlid= CreateBtree();}return t;
} 

(2)用广义表法输出二叉树

//用广义表法输出二叉树
void ShowBTree(BT *T){if(T!=NULL){//当二叉树非空时 printf("%c",T->data);//输出该结点数据域 if(T->lchlid!=NULL){//若其左子树非空 printf("(");//输出左括号 ShowBTree(T->lchild);//递归调用输出其左子树各个结点 if(T->rchlid!=NULL){//若其右子树非空 printf(",");//输出“,” ShowBTree(T->rchild);//递归调用输出其右子树各个结点 }printf(")");}elseif(T->rchild!=NULL){//若其左子树为空,右子树不为空 printf("(");//输出括号 ShowBTree(T->lchild);//递归调用输出其左子树各个结点 if(T->rchlid!=NULL){//若其右子树不为空 printf(",");//输出“,” ShowBTree(T->rchild);//递归调用输出右子树各个结点 }printf(")");}}
}  

(3)统计二叉树叶子结点数目

//统计二叉树叶子结点数目
void Leafnum(BT *T){if(T){//若树不为空 if(T->lchild==NULL&&T->rchild==NULL)coun++;Leafnum(T->lchild);//递归统计T的左子树叶子结点 Leafnum(T->rchild);//递归统计T的右子树叶子结点 }
} 

(4)求二叉树结点总数

//求二叉树结点总数
void Leafnum(BT *T){if(T){//若树不为空 coun++;Leafnum(T->lchild);//递归统计T的左子树叶子结点 Leafnum(T->rchild);//递归统计T的右子树叶子结点 }
} 

(5)求二叉树的深度

//求二叉树的深度
int TreeDepth(BT *T){int ldep,rdep;if(T==NULL){return 0;else{ldep=TreeDepth(T->lchild);//递归统计T的左子树深度 rdep=TreeDepth(t->rchild);//递归统计T的右子树深度 if(ldep>rdep)return ldep+1;elsereturn rdep+1;}}
} 

(6)复制二叉树

//复制二叉树 
int Copy(BT *T,BT &NewT){if(T==NULL){NewT=new BiTNode; NewT->data=T->data;Copy(T->lchild,NewT->lchild);//递归复制左子树 Copy(T->rchild,NewT->rchild);//递归复制右子树 }
} 

7、线索二叉树

利用二叉链表中的空指针域:
如果某个结点的左孩子为空,则将空的左孩子指针域改为指向其前驱;如果某结点的右孩子为空,则将空的右孩子指针域改为指向其后继
——这种改变指向的指针称为“线索”
加上了线索的二叉树称为线索二叉树(Threaded Binary Tree)对二叉树按某种遍历次序使其变为线索二叉树的过程叫线索化
为区分Irchid和rchild指针到底是指向孩子的指针,还是指向前驱或者后继的指针,对二叉链表中每个结点增设两个标志域 Itag和rtag,并约定:
为区分Irchid和rchild指针到底是指向孩子的指针,还是指向削驱现台后继的指针,对二叉链表中每个结点增设两个标志域 Itag和rtag,并约定:
ltag = 0 Ichild 指向该结点的左孩子
ltag = 1 Ichild 指向该结点的前驱
rtag = 0 rchild 指向该结点的右孩子
rtag = 1 rchild 指向该结点的后继
这样,结点的结构为:
在这里插入图片描述

typedef struct BiThrNode{int data;int Itag, rtag;struct BiThrNode *lchild,rchild;}BiThrNode,*BiThrTree ;

例8、画出以下二叉树对应的中序线索二叉树。
该二叉树中序遍历结果为: H,D, I,B,E, A, F,C, G
在这里插入图片描述
增设了一个头结点:
ltag=O, Ichild指向根结点,
rtag=1, rchild指向遍历序列中最后一个结点
遍历序列中第一个结点的lc域和最后一个结点的rc域都指向头结点
在这里插入图片描述

三、树与二叉树的转换

1、树转换成二叉树

①加线:在兄弟之间加一连线
②抹线:对每个结点,除了其左孩子外,去除其与其余孩子之间的关系
③旋转:以树的根结点为轴心,将整树顺时针转45°
树变二叉树:兄弟相连留长子
例9:将树转换成二叉树
在这里插入图片描述

2、二叉树变树

①加线:若p结点是双亲结点的左孩子,则将p的右孩子,右孩子的右孩子…沿分支找到的所有右孩子,都与p的双亲用线连起来
②抹线:抹掉原二叉树中双亲与右孩子之间的连线
③调整:将结点按层次排列,形成树结构
二叉树变树:左孩右右连双亲,去掉原来右孩线。
例10:将二叉树转换成树
在这里插入图片描述

四、哈夫曼树

哈夫曼树(Huffman Tree)是一种特殊的二叉树,这种树的所有的叶子结点都有权值,从而构造出带路径长度最短的二叉树,即哈夫曼树,又称最优树。

1、相关概率与定义

(1)路径:从树中一个结点到另一个结点之间的分支构成这两个结点间的路径。
(2)结点的路径长度:两结点间路径上的分支数。
在这里插入图片描述 在这里插入图片描述
(a)从A到 B,C,D, E, F, G,H,l的路径长度分别为1,1,2,2,3,3,4,4。
(b)从A到B,C,D, E, F, G,H,I的路径长度分别为1,1,2,2,2,2,3,3。
(3)树的路径长度:从树根到每一个结点的路径长度之和。记作:TL
在这里插入图片描述
TL (a)=0+1+1+2+2+3+3+4+4=20
TL (b)=0+1+1+2+2+2+2++3+3=16
结点数目相同的二叉树中,完全二叉树是路径长度最短的二叉树。
(4)权(weight):将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。
(5)结点的带权路径长度:从根结点到该结点之间的路径长度与该结点的权的乘积。树的带权路径长度:树中所有叶子结点的带权路径长度之和。记作:

在这里插入图片描述
例11:有4个结点a, b, c d,权值分别为7,5.2,4,构造以此4个结点为叶子结点的二叉树:
在这里插入图片描述
带权路径长度是:
(a)WPL=7x2+5x2+2x2+4x2= 36
(b)WPL=7x3+5x3+2x1+4×2= 46

  • 哈夫曼树:最优树,带权路径长度(WPL)最短的树。
  • “带权路径长度最短”是在“度相同”的树中比较而得的结果,因此有最优二叉树、最优三叉树之称等等。
  • 哈夫曼树:最优二叉树,带权路径长度(WPL)最短的二叉树。因为构造这种树的算法是由哈夫曼教授于1952年提出的,所以被称为哈夫曼树,相应的算法称为哈夫曼算法。
  • 满二叉树不一定是哈夫曼树,哈夫曼树中权越大的叶子离根越近

2、哈夫曼树的构造与算法

(1)哈夫曼算法(构造哈夫曼树的方法)

  • 根据n个给定的权值{W1, W2…,Wn}构成n棵二叉树的森林F={T1,,T5, …,Tn},其中T只有一个带权为wi的根结点。构造森林全是根
  • 在F中选取两棵根结点的权值最小的树作为左右子树,构造一棵新的二叉树,且设置新的二叉树的根结点的权值为其左右子树上根结点的权值之和。选用两小造新树
  • 在F中删除这两棵树,同时将新得到的二叉树加入森林中。删除两小添新人
  • 重复(2)和(3),直到森林中只有一棵树为止,这棵树即为哈夫曼树。
    例12:有4个结点a, b, c, d,权值分别为7,5,2,4,构造哈夫曼树。
    在这里插入图片描述
  • 包含n棵树的森林要经过n-1次合并才能形成哈夫曼树,共产生n-1个新结点
  • 包含n个叶子结点的哈夫曼树中共有2n-1个结点。
  • 哈夫曼树的结点的度数为О或2,没有度为1的结点。
    (2)哈夫曼树构造算法的实现
void CreatHuffmanTree (HuffmanTree HT, int n){//构造哈夫曼树——哈夫曼算法 if(n<=1)return;HT=new HTNode[mt1];//Q号单元未用,HT[m]表示根结点for(i=1;i<=m;++i){//将2n-1个元素的Ich、rch、parent置为0HT[i].lch=O; HT[i].rch=O; HT[i].parent=O;}for(i=1;j<=n;++i) cin>>HT[i].weight;//输入前n个元素的weight值//初始化结束,下面开始建立哈夫曼树for( i=n+1;i<=m; i++){//合并产生n-1个结点——构造Huffman树Select(HT, i-1, s1, s2);//在HT[k](1≤k≤i-1)中选择两个其双亲域为0,//且权值最小的结点,并返回它们在HT中的序号s1和s2HT[s1].parent=i;HT[s2] .parent=i;//表示从F中删除s1,s2HT[i].Ich=s1; HT[li].rch=s2 ;//s1,s2分别作为i的左右孩子    HT[i].weight=HT[s1].weight +HT[s2] .weight;//i的权值为左右孩子权值之和}           
}

3、哈夫曼编码

在远程通讯中,要将待传字符转换成由二进制的字符串:
设要传送的字符为:
在这里插入图片描述 在这里插入图片描述
若将编码设计为长度不等的二进制编码,即让待传字符串中出现次数较多的字符采用尽可能短的编码,则转换的二进制字符串便可能减少。
问题:什么样的前缀码能使得电文总长最短?
——哈夫曼编码
方法:

  • 统计字符集中每个字符在电文中出现的平均概率(概率越大,
    要求编码越短)。
  • 利用哈夫曼树的特点:权越大的叶子离根越近;将每个字符的概率值作为权值,构造哈夫曼树。则概率越大的结点,路径越短。3、在哈夫曼树的每个分支上标上O或1:结点的左分支标0,右分支标1
    把从根到每个叶子的路径上的标号连接起来,作为该叶子代表的字符的编码。
    例13:为什么哈夫曼编码能够保证是前缀编码?
    答:因为没有一片树叶是另一片树叶的祖先,所以每个叶结点的编码就不可能是其它叶结点编码的前缀
    例14:为什么哈夫曼编码能够保证字符编码总长最短?
    答:因为哈夫曼树的带权路径长度最短,故字符编码的总长最短。
  • 性质1哈夫曼编码是前缀码·
  • 性质2哈夫曼编码是最优前缀码

http://chatgpt.dhexx.cn/article/1mKUbdSb.shtml

相关文章

【数据结构与算法】程序内功篇六--树

程序内功篇六--树 一、树1、树的含义2、树的特点(选看)3、树的逻辑结构 二、二叉树1、二叉树的含义2、二叉树性质3、二叉树-顺序存储4、二叉树-链式存储5、二叉树的遍历6、二叉树创建与遍历C程序的实现&#xff08;1&#xff09;二叉树的创建&#xff08;2&#xff09;前序遍历…

数据结构---与树相关的知识

与树有关的一系列知识: 树,二叉树,满二叉树,完全二叉树,文章还没完,我会后序补充的 一: 树(了解就行)1.1 概念1.2 一些与树相关的重要概念1.3 树的表示形式 二: 二叉树(非常重要,重点掌握)2.1 概念2.2 两种特殊的二叉树2.2.1 满二叉树2.2.2 完全二叉树 2.3 二叉树的性质2.4 二叉…

Java数据结构--树1

Java数据结构--树 一、二叉树入门1.1 树的基本定义1.2 树的相关术语1.3 二叉树的基本定义1.4 二叉查找树的创建1.4.1 二叉树的结点类1.4.2 二叉查找树API设计1.4.3 二叉查找树实现1.4.4 二叉查找树其他便捷方法1.4.4.1 查找二叉树中最小的键1.4.4.2 查找二叉树中最大的键 1.5 二…

树 一

文章目录 1.查找二分查找判定树 2. 树(Tree)2.1 树的术语2.2树的表示&#xff1a;儿子兄弟表示法 3. 二叉树&#xff08;Binary Tree&#xff09;3.1 特殊结构二叉树3.2 二叉树的性质3.3 二叉树的存储3.4二叉树的遍历 分层次组织管理上更有效地操作。 1.查找 静态查找&#xf…

树一:邂逅入门篇

一、树的概念 树是一种典型的非线性结构&#xff0c;是表达有层次特性的图结构的一种方法。 1.1 基本术语 术语描述空树当n0 时称为空树。根结点根结点是一个没有双亲结点的结点。一棵树最多一个。例如&#xff1a;A边结点之间的连线叶子结点没有孩子结点的结点。例如&#x…

树一:定义及存储

树的定义&#xff1a; 树是一种非线性的数据结构。树是由 n (n > 0) 个结点组成的有序集合。 如果 n 为0&#xff0c;称为空树&#xff1b;如果 n > 0, 则&#xff1a; 有一个结点称为根结点&#xff08;root&#xff09;&#xff0c;它有直接后继&#xff0c;但没有直接…

mysql 创建索引规则

1、表的主键、外键必须有索引&#xff1b; 2、数据量超过300的表应该有索引&#xff1b; 3、经常与其他表进行连接的表&#xff0c;在连接字段上应该建立索引&#xff1b; 4、经常出现在Where子句中的字段&#xff0c;特别是大表的字段&#xff0c;应该建立索引&#xff1b; 5、…

mysql分区表之三:MySQL分区建索引,唯一索引

介绍 mysql分区后每个分区成了独立的文件&#xff0c;虽然从逻辑上还是一张表其实已经分成了多张独立的表&#xff0c;从“information_schema.INNODB_SYS_TABLES”系统表可以看到每个分区都存在独立的TABLE_ID,由于Innodb数据和索引都是保存在".ibd"文件当中&#…

分享mysql创建索引的3种方法

大家应该都知道索引的建立对于MySQL数据库的高效运行是很重要的,索引可以大大提升MySQL的检索速度,下面这篇文章主要给大家介绍了关于mysql创建索引的3种方法,需要的朋友可以参考下 1、使用CREATE INDEX创建&#xff0c;语法如下&#xff1a; 1 CREATE INDEX indexName ON tab…

js 监听浏览器刷新还是关闭事件

// $(window).bind(beforeunload,function(){return 您输入的内容尚未保存&#xff0c;确定离开此页面吗&#xff1f;;}); // window.onbeforeunload function() { return "确定离开此页面吗&#xff1f;"; }; // function myFunction() {return "自定…

浏览器刷新和页面手动为什么不一样?

Fiddler(2):AutoResponse修改返回结果_mb5fed6ec4336ce的技术博客_51CTO博客Fiddler(2):AutoResponse修改返回结果&#xff0c;前言怎么修改接口的返回数据呢步骤1.抓包&#xff0c;找到要拦截的请求&#xff0c;然后在AutoResponder中AddRule&#xff1a;2.在RuleEditor中的第…

vue监听浏览器刷新和关闭事件,并在页面关闭/刷新前发送请求

vue监听浏览器刷新和关闭事件&#xff0c;并在页面关闭/刷新前发送请求 1.需求背景&#xff1a;2.需求分析&#xff1a;3.实现方式&#xff1a;4.实现方式解析&#xff1a;1&#xff09;浏览器页面事件基础2&#xff09;在mounted监听beforeunload和unload事件 5.存在的问题/风…

浏览器刷新和关闭时显示提示信息

vue 刷新和关闭浏览器时显示提示信息 使用onbeforeunload事件 mounted() {window.onbeforeunload e > {e e || window.eventif (e) {e.returnValue 关闭提示}return 关闭提示}} }, beforeDestroy() {window.onbeforeunload null },如果是所有页面都需要页面销毁显示提…

【Vue实用功能】Vue监听浏览器刷新和关闭事件

Vue监听浏览器刷新和关闭事件 在前端开发中&#xff0c;我们通常会遇到这样的需求&#xff0c;用户离开、刷新页面前&#xff0c;修改数据未进行保存操作&#xff0c;需要提示框提醒用户 效果实现 methods: {/** 在刷新和关闭之前询问 **/beforeRefreshClose() {let self t…

vue监听浏览器刷新和关闭;

注意&#xff1a;区分不了浏览器是触发了刷新还是关闭&#xff0c;而且提示的弹框是无法自定义的&#xff1b;如果有大佬有方法能区分&#xff0c;还请评论学习一下&#xff01;感谢&#xff01; 代码可直接复制&#xff1a; <template><div><div /></di…

JS阻止浏览器刷新的方法

直接先给朋友们上阻止浏览器刷新的代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv&quo…

VSCODE同步浏览器刷新

VSCODE同步浏览器刷新 安装插件 live server

java中foreach的用法

文章目录 前言语法用法用法1&#xff1a;输出一维数组用法2&#xff1a;输出二维数组foreach的局限性什么是索引 总结 前言 java中foreach,可以认为是增强版的for语句循环&#xff0c;它可以减少代码量&#xff0c;但是不是所有的foreach都可以代替for循环。 语法 foreach的…

JAVA实现九九乘法表

用java语言实现九九乘法表&#xff0c;这里使用的是for循环 public class NineNineDemo{public static void main(String[] args){int i1;//对行变量赋值int j1;//对列变量赋值for(i1;i<9;i){for(j1;j<i;j){//行变量外循环&#xff1b;列变量内循环System.out.print(i&q…

Java的ASCII编码表

数字和字符的对照关系表&#xff08;编码表&#xff09;&#xff1a; ASCII码表&#xff1a;American Standard Code for Information Interchange, 美国信息交换标准代码。 Unicode码表&#xff1a;万国码。也是数字和符号的对照关系&#xff0c;开头0-127部分和ASCII完全一样…