【数据结构(C语言实现)】二叉树

对二叉树的知识点做个简单的总结

【数据结构(C语言实现)】二叉树

一、二叉树的存储表示

1.顺序存储

对于完全二叉树,可以采用数组存储,从上到下,从左到右依次编号作为数组下标;

对于一般二叉树,可以再一般二叉树中加空结点改成完全二叉树,然后用数组存储

理论上可行,但有极大的空间浪费,不可取。

2.链式存储

实用性强,接下来的算法实现都是基于此。
在这里插入图片描述

对二叉树链接表示的扩展形成双向链接结构:
在这里插入图片描述

二、二叉树的基本运算

  • Create(bt):创建空二叉树,root置NULL。
  • NewNode(x,ln,rn):创建新结点,x为数据,ln和rn为左右孩子。返回新创建的结点
  • Root(bt,x):二叉树非空则用x存储根节点的值并返回TRUE,否则返回FALSE。
  • MakeTree(bt,x,left,right):将left和right两个树合并成一棵根节点的数据为x的二叉树bt,根节点的数据是x,left和right是左右子树。在这里插入图片描述

三、二叉树的遍历

1.深度优先

  • 先序遍历算法在这里插入图片描述

  • 中序遍历算法在这里插入图片描述

  • 后序遍历算法在这里插入图片描述

已知先序/后序,还有中序序列,可以确定唯一一个二叉树。

如果结点数>1,则已知先序和后序无法确定唯一一个二叉树。

2.宽度优先(层次遍历)

采用队列实现,是非递归的,算法思想如下:

  • 根节点进队
  • 进入循环,循环条件是队列不为空
    • 访问当前队头结点并输出,队头结点出队
    • 左孩子存在则入队。
    • 右孩子存在则入队。
    • 下一步循环判断。

在这里插入图片描述

四、二叉树的结点数目计算和二叉树的清空操作

1.计算结点数目

算法思想如下:

  • 每一个子树的结点个数都是等于该子树的左右子树的和加1。

在这里插入图片描述

1的位置决定了这个函数满足的遍历思想,如上的1在两个Size后面,所以满足后序遍历,以此类推。

2.清空二叉树

在这里插入图片描述

以上函数满足后序遍历思想,但仅仅简单地移动free函数地位置不能改变其满足的遍历思想,因为free函数需要在Clear之后出现,才不会导致找不到左右子树的情况。

五、树和森林

1.树、森林、二叉树的转换

(1)树——>二叉树
  • 树中所有兄弟连线
  • 保留结点与第一个孩子的连线,其余删除。
  • 横变右子树,竖变左子树调整

在这里插入图片描述

将一棵树转换成二叉树,该二叉树的根节点一定没有右子树。

(2)森林——>二叉树
  • 将森林的每棵树变成二叉树
  • 合并所有二叉树(后一个二叉树为前一个二叉树的根节点的右子树)

在这里插入图片描述

(3)二叉树——>树/森林
  • 如果一个二叉树的根节点只有左子树,那么它转换成的是树;

  • 如果一个二叉树的根节点既有左子树又有右子树,那么它转换成的是森林。

实现方法:

  • 左子树变竖,右子树变横调整
  • 水平连线的第一个结点的父结点与该水平线的其他结点连线
  • 去除所有水平连线

二叉树转树:

在这里插入图片描述

不难看出二叉树的左孩子在转换前后父子关系不变,而右孩子发生改变

二叉树转森林:

在这里插入图片描述

从一个二叉树的根节点以从右孩子到右孩子的右孩子的方向向下遍历,直至到一个结点无右孩子,形成的路径上结点个数就是该二叉树生成的森林中树的个数。

2.树的存储表示

  • 多重链表表示法:结构简单,但易造成空间浪费。在这里插入图片描述

  • 孩子兄弟表示法:存储某结点的第一个孩子和兄弟结点,即森林对应的二叉树的链表表示法。在这里插入图片描述

  • 三重链表表示法:在孩子兄弟表示法的基础上新增一个parent指向双亲结点在这里插入图片描述

  • 双亲表示法:是一种顺序结构,存储某结点的双亲结点的下标和该结点的数据在这里插入图片描述

  • 带右链的先序表示法:是一种顺序结构在这里插入图片描述
    在这里插入图片描述

3.树和森林的遍历

  • 先序和中序遍历:

森林的先序和中序遍历等价于把森林转化成对应的二叉树,再进行先序和中序遍历;对森林的先序和中序遍历等价于对森林的每个树进行先序和中序遍历的简单拼接

  • 后序遍历:

    后序遍历第一棵树的子树构成的森林;

    后序遍历其余树构成的森林;

    访问第一棵树的根节点;

    森林的后序遍历等价于把森林转化成对应的二叉树,再进行后序遍历。不等价于对森林的每个树后序遍历的简单拼接。

  • 层次遍历:在这里插入图片描述

六、堆和优先权队列

最小堆:每个结点的数据都小于等于其孩子结点的完全二叉树

最大堆:每个结点的数据都大于等于其孩子结点的完全二叉树

堆是完全二叉树,可用顺序结构存储。

1.建堆运算

在这里插入图片描述
向下调整的算法

  • 当前元素与左右孩子比较,较小的那个孩子比当前结点还要小就把两个替换,交换后当前元素位置更新,其再跟左右孩子比较,直到比两个孩子的值都小。

在这里插入图片描述

2.优先权队列

当前为最小堆(最大堆)的前提下:

  • 进队:新元素放队尾,新元素进行向上调整操作,从该结点开始向上调整使之满足最小(大)堆要求,直至不能调整,时间复杂度: O ( l o g 2 n ) O(log_2n) O(log2n)

  • 出队:用堆尾元素覆盖堆顶元素,然后对0号元素进行向下调整,时间复杂度: O ( l o g 2 n ) O(log_2n) O(log2n)

七、哈夫曼树和哈夫曼编码

树的内路径长度:除了叶结点外,从根节点到其他结点路径的长度和

树的外路径长度:从根节点到树中所有叶子结点的路径长度和

设扩充二叉树的内路径长度和外路径长度分别是I和E,n是非叶结点的个数。则有 E = I + 2 n E=I+2n E=I+2n

树的加权路径长度(WPL):等于叶结点的加权路径长度之和。代表一个文本转化成编码后的总编码长度

哈夫曼树是一种具有最小加权路径长度的扩充二叉树。

的路径长度和

设扩充二叉树的内路径长度和外路径长度分别是I和E,n是非叶结点的个数。则有 E = I + 2 n E=I+2n E=I+2n

树的加权路径长度(WPL):等于叶结点的加权路径长度之和。代表一个文本转化成编码后的总编码长度

哈夫曼树是一种具有最小加权路径长度的扩充二叉树。

在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Em0s_Er1t

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值