5.3 二叉树的遍历和线索二叉树
基础概念
相关提炼内容见 tree-traversal。
二叉树的遍历
先序遍历 PreOrder
遍历结点的顺序如下,先是 根结点、再是左子树,最后右子树
1 1
/ \ => / \
2 3 2 5
/ \ / \
3 4 6 7
先序遍历的算法实现(递归)
void PreOrder(BiTree T) {
if (T != NULL){ // 如果二叉树非空,则继续
visit(T); // 访问根结点内容
PreOrder(T->lchild); // 访问左子树内容
PreOrder(T->rchild); // 访问右子树内容
}
}中序遍历 InOrder
遍历结点的顺序如下,先是 左子树、再是根节点,最后右子树
2 4
/ \ => / \
1 3 2 6
/ \ / \
1 3 5 7
中序遍历的算法实现(递归)
void InOrder(BiTree T) {
if (T != NULL){
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}后续遍历 PostOrder
遍历结点的顺序如下,先是 左子树、再是根节点,最后右子树
3 7
/ \ => / \
1 2 3 6
/ \ / \
1 2 4 5
void PostOrder(BiTree T) {
if (T != NULL){
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
递归算法和非递归算法的转换
中序遍历的非递归算法
void InOrder2(BiTree T, SqStack S) {
InitStack(S);
BiTree p = T;
while (p || !IsEmpty(S)) {
if (p) {
Push(S, p);
p = p->lchild;
}
else {
Pop(S, p);
visit(p);
p = p->rchild;
}
}
}先序遍历非递归
TODO
后续遍历非递归(比较难)
TODO
层次遍历
字面意思,一行一行遍历
1
/ \
2 3
/ \ / \
4 5 6 7
void LevelOrder(BiNode T) { // 输入根结点
InitQueue(Q)
BiTree p;
EnQueue(Q, T);
while (!IsEmpty(Q)) { // 判断队列是否为空
DeQueue(Q, p);
visit(p); // 访问p结点
if (p->lchild != NULL)
EnQueue(Q, p->lchild);
if (p->rchild != NULL)
EnQueue(Q, p->rchild);
}
}二级推论
- (先序 + 中序) => 唯一的二叉树
- (后序 + 中序) => 唯一的二叉树
- (层序 + 中序) => 唯一的二叉树
线索二叉树
TODO