各种树及其性质

定义

  • 树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合

性质

  • 树中的结点数=所有结点的度数之和+1
  • 度为 m 的树中第 i 层至多有 m i-1个节点(i≥1)
  • 高度为 h 的 m 叉树至多有(mh-1)/(m-1)
    在这里插入图片描述

二叉树

定义

  • 本身是有序树;
  • 树中包含的各个节点的度不能超过 2
    在这里插入图片描述

性质

  • 二叉树中,第 i 层最多有 2i-1 个结点。
    在这里插入图片描述

  • 如果二叉树的深度为 K,那么此二叉树最多有 2K-1 个结点。

  • 二叉树中,终端结点数(叶子结点数)为 n0,度为 2 的结点数为 n2,则 n0=n2+1。
    在这里插入图片描述

  • 包含n个结点的二叉树的高度至少为log2 (n+1)

二叉树的顺序存储结构

在这里插入图片描述

  • ^ 表示并不存在的空结点(也可以用0表示)
  • 空间利用率太低
  • 这种存储结构从数组下标1开始存储树中的结点,才能根据性质来计算孩子结点在数组中的位置

二叉树的链式存储结构

二叉链表存储
  • 存储结构
    在这里插入图片描述

  • 两种二叉链表
    在这里插入图片描述

二叉树的遍历

  • 序指的是根结点在何时被访问

  • 先序、中序、后序指的是父节点被访问的次序
    在这里插入图片描述

  • 先序遍历:遍历顺序规则为【根左右】

  • 中序遍历:遍历顺序规则为【左根右】

  • 后序遍历:遍历顺序规则为【左右根】

template <typename T> struct BinTreeNode {
    T data; //数据域
    BinTreeNode * LeftChild; //左孩子节点指针
    BinTreeNode * RightChild; //右孩子节点指针
    BinTreeNode * parent; //父节点指针
};
先序
  • 考察到一个节点后,即刻输出该节点的值,并继续遍历其左右子树
void travPre_R(BinTreeNode<T> * root) {
    if (!root) return;
    cout << root->data;
    travPre_R(root->LeftChild);
    travPre_R(root->RightChild);
}
中序
  • 考察到一个节点后,将其暂存,遍历完左子树后,再输出该节点的值,然后遍历右子树
void travIn_R(BinTreeNode<T> * root) {
    if (!root)
        return;
    travPre_R(root->LeftChild);
    cout << root->data;
    travPre_R(root->RightChild);
}
后序
  • 考察到一个节点后,将其暂存,遍历完左右子树后,再输出该节点的值
void travPost_R(BinTreeNode<T> * root) {
    if (!root)
        return;
    travPost_R(root->LeftChild);
    travPost_R(root->RightChild);
    cout << root->data;
}
层次

满二叉树

定义

  • 高度为h,并且有2h –1个结点的二叉树,被称为满二叉树
  • 如果一棵二叉树的结点要么是叶子结点,要么它有两个子结点,这样的树就是满二叉树
    在这里插入图片描述

性质

  • 满二叉树中第 i 层的节点数为 2n-1 个。
  • 深度为 k 的满二叉树必有 2k-1 个节点 ,叶子数为 2k-1
  • 满二叉树中不存在度为 1 的节点,每一个分支点中都两棵深度相同的子树,且叶子节点都在最底层。
  • 具有 n 个节点的满二叉树的深度为 log2(n+1)。

完全二叉树

定义

  • 一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下一层的叶结点集中在靠左的若干位置上。这样的二叉树称为完全二叉树。
  • 如果二叉树中除去最后一层节点为满二叉树,且最后一层的结点依次从左到右分布,则此二叉树被称为完全二叉树。
    在这里插入图片描述

性质

在这里插入图片描述

二叉排序树(BST)

定义

  • 又叫二叉查找树
  • 左子树所有的关键字小于根结点的关键字
  • 右子树所有的关键字大于根节点的关键字
  • 左子树和右子树又各是一个二叉排序树

性质

1、若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
2、若它的右子树不空,则右子树上所有节点的值均大于其根节点的值。
3、任何节点的键值一定大于其左子树中的每一个节点的键值,并小于其右子树中的每一个节点的键值。

目的

  • 提高查找和插入删除关键字的速度

平衡二叉树(AVL树)

定义

  • 也被称为高度平衡树
  • 它必须是二叉查找树
  • 任何一结点的左子树和右子树的深度之差不超过1
  • 若将二叉树节点的平衡因子BF定义为该节点的左子树的深度减去它的右子树的深度,则平衡二叉树上所有节点的平衡因子只可能为-1,0,1
  • AVL树的查找平均复杂度是O(log(n))

意义

  • 二叉搜索树一定程度上可以提高搜索效率,但是当原序列有序时,例如序列 A = {1,2,3,4,5,6},构造二叉搜索树如图 。依据此序列构造的二叉搜索树为右斜树,同时二叉树退化成单链表,搜索效率降低为 O(n)
    在这里插入图片描述

平衡因子

  • 某节点的左子树与右子树的高度(深度)差即为该节点的平衡因子(BF,Balance Factor),平衡二叉树中不存在平衡因子大于 1 的节点。在一棵平衡二叉树中,节点的平衡因子只能取 0 、1 或者 -1 ,分别对应着左右子树等高,左子树比较高,右子树比较高

转换

  • 平衡二叉树的失衡调整主要是通过旋转最小失衡子树来实现的。根据旋转的方向有两种处理方式,左旋 与 右旋

最小不平衡子树

  • 距离插入节点最近的,且平衡因子的绝对值大于1的节点为根的子树
    在这里插入图片描述
LL 型

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

RR型

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

LR型

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

RL型

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

线索二叉树

定义

  • 在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化
  • 对一棵二叉树中所有节点的空指针域按照某种遍历方式加线索的过程叫作线索化,被线索化了的二叉树称为线索二叉树

原理

  • 遍历二叉树的原理其实就是以一定规则将二叉树中的结点排列成一个线性序列,得到二叉树中结点的先序序列、中序序列或后序序列。这些线性序列中的每一个元素都有且仅有一个前驱结点和后继结点。

结点结构

在这里插入图片描述

  • LTag为0是指向该结点的左孩子,为1时指向该结点的前驱

  • RTag为0是指向该结点的右孩子,为1时指向该结点的后继

在这里插入图片描述

为什么

  • 知道了“前驱”和“后继”信息,就可以把二叉树看作一个链表结构,从而可以像遍历链表那样来遍历二叉树,进而提高效率

森林

定义

  • 只要没有回路的连通图就是树。森林是指互相不交并树的集合。
  • 森林(forest)是m(m≥0)棵互不相交的树的集合。任何一棵树,删除了根结点就变成了森林。

森林跟二叉树的转换

森林转换为二叉树
  • 初始
    在这里插入图片描述
  • 将森林中的每棵树变为二叉树
    在这里插入图片描述
  • 将各二叉树的根节点从左到右连在一起,形成二叉树
    在这里插入图片描述
  • 调整位置
    在这里插入图片描述
二叉树转换为森林
  • 初始
    在这里插入图片描述
  • 若结点X是双亲Y的左孩子,则把X的右孩子,右孩子的右孩子…都和 Y用线连起来
    在这里插入图片描述
  • 去掉所有双亲到右孩子间的连线
    在这里插入图片描述
  • 调整位置
    在这里插入图片描述

哈夫曼树

定义

  • 给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
  • 路径是指在一棵树中,从一个节点到另一个节点之间的分支构成的通路
  • 节点的带权路径长度指的是从根节点到该节点之间的路径长度与该节点权的乘积
  • 树的带权路径长度指的是所有叶子节点的带权路径长度之和
    在这里插入图片描述

哈夫曼编码

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值