一. 树的定义和基本术语
1. 结点之间的关系描述
①祖先结点 ②子孙结点 ③父结点(双亲结点) ④孩子结点 ⑤兄弟结点 ⑥堂兄弟结点
路径:只能从上往下
路径长度:经过几条边
2. 结点、树的属性描述
属性:结点的深度(层次)——从上往下数
结点的高度——从下往上数
树的高度(深度)——总共有多少层
结点的度——有几个分支结点(类似于出度)
树的度——各结点的度的最大值
3. 有序树 VS 无序树
有序树:各子树从左至右是有次序的
无序树:各子树从左至右是无序的
森林:由m (m>=0)棵树组成
4. 树的性质
① 结点数=总度数+1
② 度为m的树、m叉树的区别
③ m叉树、度为m的树第i层至多有个结点(i>=1)
④ 高度为h的m叉树至多有个结点
等比数列求和公式:
⑤ 高度为h的m叉树至少有h个结点
高为h、度为m的树至少有h+m-1个结点
⑥ 具有n个结点的m叉树的最小高度为
二. 二叉树的定义和基本概念
每个结点至多两棵子树,左右子树不可颠倒(有序树)
1. 几个特殊的二叉树
①满二叉树:高度为h,含有个结点的二叉树;按层序从1开始编号,结点i的左孩子为2i,右孩子为2i+1;结点的父节点为
②完全二叉树:每个结点编号与满二叉树对应的树。
特点:i)最后两层可能有叶子结点
ii)最多只有一个度为1的结点
iii)i<=为分支结点,i>=为叶子结点
③二叉排序树
左子树上所有结点的关键字均小于根节点的关键字
右子树上所有结点的关键字均大于根节点的关键字
左子树和右子树有分别各是一棵二叉排序树
“左小右大”,常用于元素的排序、搜索
④平衡二叉树
树上任何一结点的左子树和右子树的深度之差不超过1
平衡二叉树能有更高的搜索效率
平衡因子:此结点往下,左子树深度-右子树深度
2. 二叉树的性质
①二叉树中,度为0的结点比度为2的结点多1个(叶子结点比二分支结点多一个)
②二叉树第i层至多个结点
③高度为h的二叉树至多有个结点
④对于完全二叉树,度为1的结点只有0或者1个(单分支结点只有一个)
三. 二叉树的存储结构
1. 二叉树的顺序存储
一定要把二叉树结点的编号与完全二叉树对应起来
/*二叉树的顺序存储*/
#define MaxSize 100
//一定要把二叉树的结点编号与完全二叉树对应起来
struct TreeNode {
ElemType value;
bool isEmpty;
};
TreeNode t[MaxSize];
for (int i = 0; i < MaxSize; i++) {
t[i].isEmpty = true;
}
2. 二叉树的链式存储
/*二叉树的链式存储*/
typedef struct BiTNode {//n个结点的二叉链表有n+1个空链域
ElemType data;
struct BiTNode* lchild, * rchild;
//若常访问父结点,可追加定义一个*parent,成为三叉链表,否则从根节点遍历会很耗时间
}BiTNode,BiTree;
//初始化树
BiTree root = NULL;
//插入根结点
root = (BiTree)malloc(sizeof(BiTNode));
root->data = { 1 };
root->lchild = NULL;
root->rchild = NULL;
//插入新结点
BiTNode* p = (BiTNode*)malloc(sizeof(BiTNode));
p->data = { 2 };
p->lchild = NULL;
p->rchild = NULL;
root->lchild = p;
四. 二叉树的先中后序遍历
1. 二叉树的遍历
①先序:根左右 ②中序:左根右 ③后序:左右根
2. 先序遍历(代码)
/*先序遍历*/
void PreOrder(BiTree T) {
if (T != NULL) {
visit(T);//访问根结点
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
T(n) = O(h+1) =O(h),h为树的高度,+1是因为叶子结点还会被当作有两个空子树。
五. 二叉树的层序遍历
1. 算法思想
①初始化一个辅助队列;②根结点入队;③若队列非空,队头出队并访问该结点,并将其左右孩子插入队尾;④重复③直到队空。
2. 代码实现
/*二叉树的层序遍历*/
void LevelOrder(BiTree T) {
LinkQueue Q;
InitQueue(Q);
BiTree p;
EnQueue(Q, T);
while (!IsEmpty(Q)) {
DeQueue(Q, p);
visit(p);
if (p->lchild != NULL)EnQueue(Q, p->lchild);
if (p->rchild != NULL)EnQueue(Q, p->rchild);
}
}
六. 由遍历序列构造二叉树
1. 由遍历序列构造二叉树
若只给出一棵二叉树的前、中、后、层序遍历序列中的一种,不能唯一确定一棵二叉树。
需要中序与其他任意一种遍历序列才能唯一确定
七. 由遍历序列构造二叉树
八. 线索二叉树的概念
九. 二叉树的线索化
十. 线索二叉树找前驱/后继