数据结构与算法(六)—— 数和二叉树
树的相关定义
- 根节点:非空树中无前驱结点的结点
- 结点的度:结点拥有的子树数量
- 树的度:树内各节点的最大度
- 叶子:度等于零的终端节点
- 孩子与双亲:结点的子树的根称为该结点的孩子,该结点称为孩子的双亲
- 祖先:从根到该结点所经分支上的所有结点
- 有序树:将树中每个结点的各子树看成是从左到右有次序的(即不能互换)
- 无序树:将树中每个结点的各子树从左到右是没有次序的(即可以互换)
二叉树的性质
- 在二叉树的第i层上至多有$2^{i-1}$个结点
- 深度为k的二叉树至多有$2^{k}-1$个结点
- 对于任何一颗二叉树T,如果其叶子数为$n_{0}$,度为2的结点数为$n_{2}$,则$n_{0} = n_{2} +1$
对于完全二叉树: - 具有n个结点的完全二叉树的深度为$\lfloor log_2(n) \rfloor$
- 对于某一编号为i的结点,它的双亲结点必为$\lfloor i/2 \rfloor$,左右孩子分别为2i、2i+1
满二叉树与完全二叉树:可以用顺序存储结构还原的树
满二叉树:深度为k,且有$2^{k}-1$个结点
完全二叉树:深度为k,每一个结点都与深度为k的满二叉树中编号为1-n的结点一一对应
特点:
- 叶子只可能分布在层次最大的两层
- 对任一结点,如果其右子树的最大层次为i,左子树的最大层次必定为i或者i+1
二叉树的存储结构
二叉树的顺序存储结构
一般只适用于存放满二叉树和完全二叉树
1 |
|
二叉树的链式存储结构
二叉链表
1 | typedef struct BiNode{ |
空指针数目 = 2n - (n-1) = n + 1
解释:n个结点会产生2n个指针域。除去头结点剩下均为孩子节点,均需要被存放在指针域,故需要占用n-1个指针域。
则空指针数目为:2n - (n -1) = n + 1
三叉链表
1 | typedef struct TriTNode{ |
遍历二叉树和搜索二叉树
遍历二叉树
遍历二叉树的三种顺序:
- 先序遍历(根左右)
- 中序遍历(左根右)
- 后序遍历(左右根)
Ex:1
由遍历序列确定二叉树:先序和后序不能确定唯一序列
- 先序竖着摆放,中序横着摆放,画表格。画完表格后:
- 找最高点M
- 在最高点M左边的区域内找最高点L
- 在最高点M右边的区域内找最高点R
- 连接L-M-R
- 用L取代M,递归下去,用R取代M,递归下去
- 后序竖着、倒着摆放,中序横着摆放,画表格。
遍历二叉树算法实现
- 先序遍历二叉树
1
2
3
4
5
6
7void PreOrderTraverse(BiTree T){
if(T!=NULL){
print(T.data);
PreOrderTraverse(T.lchild);
PreOrderTraverse(T.rchild);
}
} - 中序遍历二叉树
1
2
3
4
5
6
7void InOrderTraverse(BiTree T){
if(T!=NULL){
InOrderTraverse(T.lchild);
print(T.data);
InOrderTraverse(T.rchild);
}
} - 后序遍历二叉树算法分析:
1
2
3
4
5
6
7void PoseOrderTraverse(BiTree T){
if(T!=NULL){
PostOrderTraverse(T.lchild);
PostOrderTraverse(T.rchild);
print(T.data);
}
} - 时间复杂度O(n) //每个结点只访问一次
- 空间复杂度O(n) //栈占用的最大辅助空间
中序遍历的非递归算法
1 | void InOrderTraverlverse(BiTree T){ |

二叉树的层次遍历(广度优先搜索)
- 创建一个队列,根节点入队
- 队列非空时出队一个元素,同时将其左右孩子入队
1
2
3
4
5
6
7
8
9
10
11
12void LevelOrder(BtNode *b){ //传入二叉树根节点
BTNode *p; //用于存放出队元素
SqQueue *qu; //用于存放结点的队列
InitQueue(qu);
enQueue(qu,b); //将根节点存入队列
while(!QueueEmpty(qu)){
deQueue(qu,p); //出队结点p
printf(p->data) //访问p结点
while(p->lchild != NULL) enQueue(qu,p->lchild) //有左孩子入队左孩子
while(!p->rchild != NULL) enQueue(qu,p->rchild) //有右孩子入队右孩子
}
}
二叉树的建立:以先序遍历为序
1 | int CreateBiTree(BiTree &T){ |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 HaruYuki's Blog!










