二叉树的存储结构
一、二叉树的顺序存储
定义
#define MaxSize 100
typedef struct TreeNode{
int value;//结点中的数据元素
bool isEmpty;//结点是否为空
};
TreeNode t[MaxSize];
定义一个长度为MaxSize的数组t,按照从上至下、从左至右的顺序依次存储完全二叉树
中的各个结点
初始化
for(int i = 0; i < MaxSize; i++){
t[i].isEmpty =true;//初始化时所有结点标记为空
}
可以让第一个位置空缺,保证数组下标和结点编号一致
几个重要常考的基本操作:
- i的左孩子:2i
- i的右孩子:2i+1
- i的父节点:[i/2]向下取整
- i所在的层次:[log2(n+1)]向上取整或[log2n]向下取整+1
若完全二叉树
中共有n个结点,则
- 判断i是否有左孩子?2i<=n?
- 判断i是否有右孩子?2i+1<=n?
- 判断i是否是叶子/分支结点?i>[n/2]向下取整?
二叉树的顺序存储中,一定要把二叉树的结点编号与完全二叉树对应起来
- i的左孩子:2i(对)
- i的右孩子:2i+1(对)
- i的父节点:[i/2]向下取整(对)
若非完全二叉树
中共有n个结点,则
- 判断i是否有左孩子?2i<=n?(错)
- 判断i是否有右孩子?2i+1<=n?(错)
- 判断i是否是叶子/分支结点?i>[n/2]向下取整?(错)
最坏情况:高度为h且只有h个结点的单支树(所有结点只有右孩子),也至少需要2^h - 1个存储单元
结论二叉树的顺序存储结构,只适合存储完全二叉树
思考:如果结点从0开始编号,该怎么算?
二、二叉树的链式存储
定义
在这里插入代码片
n个结点的二叉链表
共有n+1个空链域(可用于构造线索二叉树)
(十分重要的结论)
初始化
在这里插入代码片
找到指定结点p的左/右孩子–超简单
如何找到指定结点p的父节点?只能从根开始遍历寻找(使用三叉链表–方便找父节点)
三叉链表的定义
在这里插入代码片