Binary Tree
文章目录
数据结构“树与二叉树”的学习
一些学习心得
树:包含n个结点的有限集
- 有且仅有一个 root 结点
- 除了 root 结点以外的其余结点可以分为许多的不相交的有限集,而这些有限集本身也是一棵树,因此可以称为 root 的子树。
二叉树:一种特殊的树
- 同样有且只有一个 root 结点
- 但是不同于树,其每一个结点只有两个互不相交的子集,分别称为左子树和右子树(不能颠倒顺序),且左,右子树本身也属于二叉树。
二叉树的性质
- 二叉树的第 i 层最多有 $2^{i-1}$ 个结点
- 深度为 k 的二叉树至多有 $2{i-2}$ 个结点
- 任何一颗二叉树,叶子结点 $n_0$ 的个数等于度为 2 的结点 $n_2$ 个数 + 1。
二叉树的两种特殊形态:
- 满二叉树
- 完全二叉树
满二叉树的特点
- 每一层的结点数都是最大结点数,即 $2^{i-1}$ 个
完全二叉树的特点
- 首先对满二叉树的结点进行编号,以root结点开始,从上往下,从左往右。假设深度为 k d,有 n 个结点的二叉树,当且仅当其中每一个结点都与深度为 k 的满二叉树中的编号从 1 至 n 的结点一一对应使,才称为完全二叉树。
两种特殊二叉树的重要特性
具有 n 个结点的完全二叉树的深度为 $\lfloor log_2n\rfloor$ +1。
如果对一棵有 n 个结点的完全二叉树( 其深度为 $\lfloor log_2n\rfloor$ +1 )的结点按层序编号,则对任一结点 i( $1\leq i \leq n$ ),有
顺序存储
链式存储
顺序存储
1
2
3
4
typedef TElemType SqBiTree[MAXSIZE];
// TElemType 在实际编程中换成所需的类型
SqBiTree bt;这种存储结构仅适用于完全二叉树,对于结点数很少的树来说是非常浪费存储空间的
链式存储
1 | typedef struct BiTNode{ |
- 在含有 n 个结点的二叉链表中有 n+1 个空链域
1
2n 个节点,每个结点 2 个指针域,共 2n 个指针域,
用掉 n-1 个指针域,剩下 2n - ( n - 1 ) 个指针域。
遍历二叉树
二叉树遍历的关键在于递归思想。
规定先先左后右,分为三种情况:
- 先(根)序遍历(DLR)
- 先访问根结点
- 先序遍历左子树
- 先序遍历右子树
- 中(根)序遍历(LDR)
- 中序遍历左子树
- 访问根结点
- 中序遍历右子树
- 后(根)序遍历(LRD)
- 后序遍历左子树
- 后续遍历右子树
- 访问根节点
例:中序遍历的递归算法
1 | void InOrderTraverse(BiTree T) { |
例:中序遍历的非递归算法
1 | void InOrderTraverse_N(BiTree T) { |
无论是递归还是非递归算法,对于 n 个结点的二叉树,其时间复杂度均为O(n),空间复杂度也为O(n)。
根据遍历序列确定二叉树
- 中序遍历 + 先序遍历
- 中序遍历 + 后序遍历
方法:先利用先(后)序序列,找到根结点。然后根据中序序列找到根节点的左,右子树,再在先序序列中取第二个结点(后序序列取倒数第二个结点),根据同样的方式,继续分割中序序列,一直递归直至完成。
注意:先序序列第一个结点就是根结点,后序序列最后一个结点是根结点。
例如:已知一棵二叉树的中序序列和后序序列分别是 BDCEAFHG 和 DECBHGFA,请画出这棵二叉树
- 第一步:根据后续序列 DECBHGFA 的最后一个结点,可以得到根结点为 A 为根结点
- 第二步:在中序序列中找到 根结点 A 两侧的左,右子树 E 和 F。此时中序序列被分成两部分 左子树部分 BDCE,和右子树部分 FHG。后序序列也被分成左,右子树两部分,DECB 和 HGF。
- 第三步:先看左子树的中序序列 BDCE,得到这部分的根节点是 B(A已经考虑完了,不再考虑),左子树的中序序列 BDCE 表示 B 结点只有右子树,是 CDE。同理,按这种方法不断递归,就可以得到一棵完整的二叉树。
二叉树遍历算法的应用
先序遍历的顺序建立二叉链表
1 | void CreateBiTree(BiTree &T) { |
中序遍历和后序遍历只需要改变最后三个语句的顺序即可
复制二叉树
1 | void Copy(BiTree T, BiTree &NewT) { |
计算二叉树的深度
1 | //二叉树的深度等于左右子树深度较大的加 1 |
统计二叉书的结点个数
1 | // 二叉树的个数等于左右子树结点数 + 1。 |
原文作者: Je Ano
原文链接: http://maxximues.github.io/2019/07/18/Binary-Tree/
许可协议: 知识共享署名-非商业性使用 4.0 国际许可协议