树与二叉树


树是一种非线性的递归结构,存储的数据元素关系为“ 一对多

1、 定义

概念:

  1. 结点:祖先结点、子孙结点、双亲结点、孩子结点、兄弟结点、根结点
  2. 度:子结点个数
  3. 分支结点(非终端结点):度大于0的结点
    叶子结点(终端结点):度为0的
    根结点:没有父节点的
  4. 层次:从根开始的层数(根为1层)
    深度:从根向下
    高度:从叶向上
  5. 路径:两个结点之间所经过结点序列(路径自上而下,同双亲的两个孩子结点不存在路径)

注:空树没有结点

树的性质:

  1. 结点数=度数+1
  2. 度为m的数第i层至多有mi-1个结点
  3. 高度h的m叉树上至多有 m h − 1 m − 1 \frac{m^h-1}{m-1} m1mh1个结点
  4. n个结点的m叉树的最小高度为 l o g m ( n ( m − 1 ) + 1 ) log_m(n(m-1)+1) logm(n(m1)+1)(向上取整数)

2、 二叉树

2.1 二叉树性质
  1. 非空二叉树上叶子结点数等于度为2的结点数加1,即n0=n2+1
    结点总数n=n0+n1+n2=n1+2n2+1
  2. 非空二叉树上第k层有至多2k-1个结点(k>=1)
  3. 高度h的二叉树至多有2h-1个结点(h>=1)
  4. n个结点的完全二叉树的高度为log2(n+1)(向上取整数)
  5. n个结点有 C 2 n n n + 1 \frac{C_{2n}^n}{n+1} n+1C2nn种不同的二叉树(与栈相同)
2.2 几种特殊的二叉树
满二叉树

除了叶子结点,每个结点度都为2
在这里插入图片描述

完全二叉树
二叉排序树
平衡二叉树
2.3 存储结构
顺序结构

用一组连续地址按从上到下,从左到右的逻辑去存储二叉树上的结点元素
(适用于完全二叉树和满二叉树)

注:1. 需要从数组下标1开始存储树中的结点
2、树的顺序存储,数组下标代表结点编号
二叉树的顺序存储,数组下标既代表结点编号,也代表个结点之间关系
3、二叉树可以采用树的存储结构储存,但树并不一定能采用二叉树的存储结构

  • 双亲表示法:用一组连续的存储空间存储树的结点,同时在每个结点中,用一个变量存储该结点的双亲结点在数组中的位置。
链式存储

二叉树的空间利用率低,适合链式

  • 孩子表示法:把每个结点的孩子结点排列起来存储成一个单链表。所以n个结点就有n个链表; 如果是叶子结点,那这个结点的孩子单链表就是空的; 然后n个单链表的的头指针又存储在一个顺序表(数组)中。
  • 孩子兄弟表示法:顾名思义就是要存储孩子和孩子结点的兄弟,具体来说,就是设置两个指针,分别指向该结 点的第一个孩子结点和这个孩子结点的右兄弟结点。

孩子兄弟表示法结点定义

typedef struct BiTNode{
    int data;  //数据域
    struct BiTNode *lchild, *rchild;  //左右孩子指针
}BiTNode,*BiTree;
2.4 线索二叉树
二叉树遍历
  1. 先序遍历(NLR)
void PreOrder(BiTree T){
    if(T!=NULL){
        visit(T); //访问根节点
        PreOrder(T->lchild); //遍历左子树
        PreOrder(T->rchild);
    }
}
  1. 中序遍历(LNR)
void InOrder(BiTree T){
    if(T!=NULL){
        InOrder(T->lchild);
        visit(T);
        InOrder(T->rchild);
    }
}
  1. 后序遍历(LRN)
void PostOrder(BiTree T){
    if(T!=NULL){
        PostOrder(T->lchild);
        PostOrder(T->rchild);
        visit(T);
    }
}
  1. 层次遍历(利用队列)
void LevelOrder(BiTree T){
    InitQueue(Q);  //初始化辅助队列
    BiTree p;
    EnQueue(Q,T); //根结点入队
    while(!IsEmpty(Q)){
        DeQueue(Q,p); //队头元素出队
        visit(p); //访问p所指结点
        if(p->lchild!=NULL)
            EnQueue(Q, p->lchild); //左子树入队列
        if(p->rchild!=NULL)
            EnQueue(Q, r->lchild); //右子树入队列 
    }
}
  1. 构建二叉树

先用先序或者后序,找到根节点,在中序里将左右子树分开。循环操作,求出树型。

构建二叉树
先序+中序确定唯一二叉树
后序+中序确定唯一二叉树

若前序和后序相反,则:

  • 二叉树高等于结点数
  • 每个分支结点至多只有左孩子或者右孩子
  • 只有一个叶子结点

遍历的作用:对于已知树求结点双亲、结点的孩子结点,求二叉树深度、二叉树的叶子结点数、判断两棵二叉树是否相同等

线索二叉树
  1. 基本概念
    为了加快查找结点前驱和后继的速度,利用链表表示的二叉树中存在大量空指针(在n个结点的二叉树中存在n+1个空指针)。

二叉树是逻辑结构
线索二叉树是物理结构(是二叉树在计算机中的一种存储结构)

线索化规定:若无左子树,令lchild指向其前驱结点;若无右子树,令rchild指向其后继结点
结点结构如下图,标志域为表明指向结点还是直接前驱
在这里插入图片描述
结点存储结构

typedef struct ThreadNode{
    int data;
    struct ThreadNode *lchild, *rchild;
    int ltag, rtg; //左右线索标志
}ThreadNode, *ThreadTree; 
  1. 构造

线索化:对二叉树进行遍历使其变为线索二叉树的过程

  1. 遍历
    注意:在进行线索树遍历时,先序和中序遍历可以直接进行,而后序遍历需要的支持

3、 树、森林

3.1 存储结构
双亲表示法

求孩子结点时需要遍历整个结构

孩子表示法

寻找双亲需要遍历n个结点中孩子链表指针域所指向的n个孩子链表

孩子兄弟表示法(二叉树表示法)

结点包含:(结点值、指向结点第一个孩子结点的指针、指向结点下一个兄弟结点的指针
方便进行树转换为二叉树操作,易于查找结点的孩子,但不适合找双亲。

3.2 树、森林与二叉树转换

树->二叉树:左指孩子,右指兄弟。根结点无兄弟,故转换后二叉树无右子树。
二叉树->树
在这里插入图片描述
森林->二叉树:1.连接所有根 2.每棵树转为二叉树 3.以第一棵树的根顺时针旋转45°
二叉树->森林:断掉根结点向右的所有线,将断开的二叉树转为树。(二叉树转为树 或者森林是唯一的)
在这里插入图片描述
注意:树->二叉树后,无右孩子的结点数=分支结点+1(除叶结点外均为分支结点)

3.3 树和森林的遍历
森林二叉树
先根遍历先序遍历先序遍历
后根遍历中序遍历中序遍历

4、 应用

4.1 二叉排序树

特性:

  1. 左子树非空,子树上所有结点关键字值都结点的关键字值
  2. 右子树非空,子树上所有结点关键字值都结点的关键字值

对二叉排序树进行中序遍历,能够得到递增的有序序列

二叉排序树的插入规则为:关键字K小于根结点就左插,大于根结点右插。

删除结点:
①删除的是叶子结点
方法:直接删去该结点即可
②删除的是仅有左子树或者右子树的结点
方法:“子承父业”
③删除的是左右子树都有的结点
方法:令后继结点代替待删除结点,然后对该后继结点进行删除操作。(前驱结点同样可以)

4.2 平衡二叉树

定义:任意结点的左右子树高度差的绝对值不超过1的二叉排序树,简称平衡树(AVL)
平衡因子:结点左右子树高度差

插入:

  1. LL(右转)
    在这里插入图片描述
  2. RR(左转)
    在这里插入图片描述
  3. LR(先左后右)
    在这里插入图片描述
  4. RL(先右后左)
    在这里插入图片描述
    注:多处不平衡时,优先转下部分树枝
    含有n个结点平衡二叉树的最大深度为O(log2n),因此,平衡二叉树的平均查找长度为O(log2n)
4.3 哈夫曼树
定义

哈夫曼树(最优二叉树):WPL最小的二叉树
带权路径长度(WPL):所有叶结点的带权路径(从根结点到该结点间路径长度与该结点的权的乘积)长度之和
W P L = ∑ i − 1 n w i l i WPL=\sum_{i-1}^nw_il_i WPL=i1nwili
如下图中所示带权路径长度为:WPL=3x7+3x5+1x2+2x4=46

在这里插入图片描述
注意:一棵有n个叶子结点的Huffman树有2n-1个结点

构建过程
  1. 从n个权值中取出两个最小的权值,然后小的放左边,构建树。根结点权值为两个权值相加为根结点权值,加入到原来的n-2个权值序列中
  2. 继续1操作,直至最终只剩下唯一根结点权值。当前树为哈夫曼树
哈夫曼编码

规定树中左子树标记0,右子树标记1。从结点开始,写出每个结点的路劲标记,即为编码。
在这里插入图片描述

上图编码为
a:0
b:10
c:110
d:111

考研tips:
本章内容多以选择题形式考察,算法题会涉及树遍历相关操作
树和二叉树的性质、遍历操作、转换(二叉树-树-森林)、存储结构和操作特性
满二叉树、完全二叉树、线索二叉树、哈夫曼树的定义和性质
二叉排序树和二叉平衡树的性质和操作


小狼的相关博文:

  1. 算法(Algorithm)与数据结构(Data Structure)——索引

  2. 数据结构和算法系列代码测试代码

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值