二叉树的性质
- 每个结点最多有两个子结点:左孩子、右孩子。
- 以它们为根的子树称为左子树、右子树。 二叉树的第i层,最多有2i-1个结点。
- 如果每一层的结点数都是满的,称为满二叉树。
- 如果满二叉树只在最后一层有缺失,并且缺失的编号都在最后,那么称为完全二叉树
二叉树的存储
1.用指针实现。
struct node{
int value; //结点的值
node *l, *r; //指向左右子结点
};
2. 用数组实现。
二叉树的遍历
- 1. 宽度优先遍历:一层层地遍历二叉树。用队列实现。
- 2. 深度优先遍历:更常用的遍历方法。
二叉树的深度优先遍历
- 先(根)序遍历
- 中(根)序遍历
- 后(根)序遍历
先(根)序遍历
- 按父、左儿子、右儿子的顺序访问:
- EBADCGFIH
- 先序遍历的第一个结点是根
先序遍历的代码很简单:
void preorder (node *root){
cout << root ->value; //输出
preorder (root ->l); //递归左子树
preorder (root ->r); //递归右子树
}
中(根)序遍历
- 按左儿子、父、右儿子的顺序访问:
- ABCDEFGHI
- 思考:结果为什么是字典序?
中序遍历的特点
- ABCDEFGHI 返回的结果:
- 根结点左边的点都在左子树上,右边的都在右子树上。
- 例如:E是根,E左边的“ABCD”在它的左子树上;
- 例如:在子树“ABCD”上,B是子树的根
- 那么“A”在它的左子树上,“CD”在它的右子树上。
中序遍历代码:
void preorder (node *root){
preorder (root ->l); //递归左子树
cout << root ->value; //输出
preorder (root ->r); //递归右子树
}
后(根)序遍历
- 按左儿子、右儿子、父的顺序访问:
- ACDBFHIGE
- 后序遍历的最后一个结点是根
三种遍历的关系
- 已知二叉树的:“中序遍历+先序遍历”,或者“中序遍历+后序遍历”,都能确定一棵树。
- 但是只有“先序遍历+后序遍历”,不能确定一棵树。
- 例如下图,它们的先序遍历都是"1 2 3",后序遍历都是"3 2 1"。
例题: hdu 1710 Binary Tree Traversals
思路:
- (1)先序遍历的第一个数是整棵树的根,例如样例中的“1”。
- 再对照中序遍历,“1”左边的“4 7 2”都在根的左子树上,
- 右边的“8 5 9 3 6”都在根的右子树上。得到下图最左子图。
- (2)递归上述过程。