二叉树的遍历算法

118 阅读2分钟
  1. 递归算法:
  • 先序遍历:
void PreOrder(BiTree T){
    if (T!=NULL){ // 根结点不为空
    visit(T); // 访问根结点
    PreOrder(T->lchild); // 递归遍历左子树
    PreOrder(T->rchild); // 递归遍历右子树
    }
}
  • 中序遍历:
void InOrder(BiTree T){
    if (T!=NULL) { // 根结点不为空
    InOrder(T->lchild); // 递归遍历左子树
    visit(T); // 访问根结点
    InOrder(T->rchild); // 递归遍历右子树
    }
}
  • 后序遍历:
void PostOrder(BiTree T) {
    if (T!=NULL){ // 根结点不为空
    PostOrder(T->lchild); // 递归遍历左子树
    PostOrder(T->rchild); // 递归遍历右子树
    visit(T); // 访问根结点
    }
}
  1. 非递归算法:
  • 先序遍历:
void PreOrder2(BiTree T){
    InitStack(S);BiTree p=T; // 初始化栈;p为遍历指针
    while (!=IsEmpty(S) || p){ // 栈不为空或 p 不为空
         if (p) { // 一路向左
             visit(p); // 访问根结点
             Push(S,p); // 将根结点入栈
             p=p->lchild; // 访问左子树
         }
         else{ // 出栈,并转向栈顶元素的右子树
             Pop(S,p); // 栈顶元素出栈
             p=p->rchild; // 访问右子树
         }
    }
}
  • 中序遍历:
void InOrder2(BiTree T){
    InitStack(S);BiTree p=T; // 初始化栈;p为遍历指针
    while (!IsEmpty(S) || p){ // 栈不为空或 p 不为空
        if (p) { // 一路向左
            Push(S,p); // p 入栈
            p=p->lchild; // 访问左子树
        }
        else {
            Pop(S,p); // 栈顶元素出栈
            visit(p); // 访问根结点
            p=p->rchild; // 访问右子树
        }
    }
}
  • 后序遍历:
void PostOrder2(BiTree T){
    InitStack(S); // 初始化栈
    BiTNode *p=T; // p 为遍历指针
    BiTNode *r=NULL; // r 为辅助指针,用于指向最近访问的结点
    while (p || !IsEmpty(S)){
        if (p) {
            Push(S,p);
            p=p->lchild;
        }
        else {
            GetTop(S,p); // 读栈顶元素
            if (p->rchild && p->rchild!=r){ // 若右子树存在且未被访问过
                p=p->rchild;
            }
            else { // 否则,弹出栈顶并访问
                Pop(S,p);
                visit(p);
                r=p; // 记录最近访问过的结点
                p=NULL; // 结点访问完,重置 p 指针
            }
        }
    }
}
  1. 层次遍历
void LevelOrder(BiTree T){
    InitQueue(Q); // 初始化辅助队列 Q
    BiTree p; // 初始化遍历指针 p
    EnQueue(Q,T); // 将根结点 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); // 右子树根结点入队
        }
    }
}