二叉树(一) 先序遍历、中序遍历、后续遍历、层次遍历的递归与非递归实现

直接看代码吧,理论知识略了,网上一搜一大把,本篇主要记录代码实现过程。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<stack>
#include<queue>
using namespace std;

/*二叉树链式存储结构*/
typedef struct BiTNode{
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

/*先序创建二叉树*/
int CreateBiTree(BiTree &T){
    char data;
    scanf("%c",&data);
    if(data=='#'){        //'#'号表示空树
        T=NULL;
    }
    else{
        T=(BiTree)malloc(sizeof(BiTNode));  //T=(BiTNode*)malloc(sizeof(BiTNode)); 也可以
        T->data=data;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
    return 0;
}

/*访问节点*/
void Visit(BiTree T){
    if(T) printf("%c ",T->data);
}

/*递归先序遍历*/
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);
    }
}

/*非递归先序遍历*/
void PreOrder2(BiTree T){
    stack<BiTree> s;            //申请树节点指针类型栈
    BiTree p = T;               //p是遍历指针
    while(p || !s.empty()){     //p不空或栈不空时循环
        if(p != NULL){
            Visit(p);           //访问节点
            s.push(p);          //根指针进栈
            p = p->lchild;      //遍历左子树
        }
        else{                   //根指针退栈,遍历右子树
            p = s.top();
            s.pop();
            p = p->rchild;
        }
    }

}

/*非递归中序遍历*/
void InOrder2(BiTree T){
    stack<BiTree> s;
    BiTree p = T;
    while(p || !s.empty()){
        if(p != NULL){
            s.push(p);
            p = p->lchild;
        }
        else{
            p = s.top();
            s.pop();
            Visit(p);
            p = p->rchild;
        }
    }
}

/*非递归后续遍历*/
void PostOrder2(BiTree T){
    stack<BiTree> s;
    BiTree p = T, r = NULL;
    while(p || !s.empty()){
        if(p != NULL){               //一直往左走
            s.push(p);
            p = p->lchild;
        }
        else{                        //向右
            p = s.top();             //取栈顶节点
            if(p->rchild && p->rchild!=r){ //如果右子树存在,且未被访问过
                p = p->rchild;       //转向右
                s.push(p);
                p = p->lchild;       //再往左走
            }
            else{                    //否则,弹出节点并访问
                s.pop();
                Visit(p);
                r = p;               //记录最近访问过的节点
                p = NULL;            //节点访问完后,重置p指针
            }
        }
    }
}

/*非递归层次遍历*/
void LevelOrder(BiTree T){
    queue<BiTree> Q;
    BiTree p = T;              //遍历指针
    Q.push(p);                 //根结点入队
    while(!Q.empty()){         //队列非空则循环
        p = Q.front();         //取队头元素
        Q.pop();
        Visit(p);
        if(p->lchild != NULL)  //左子树非空,则左子树入队列
            Q.push(p->lchild);
        if(p->rchild != NULL)  //右子树非空,则右子树入队列
            Q.push(p->rchild);
    }
}

int main(){
    BiTree T;
    CreateBiTree(T);

    printf("————————————————————\n");
    printf("递归先序遍历:");
    PreOrder(T);

    printf("\n递归中序遍历:");
    InOrder(T);

    printf("\n递归后序遍历:");
    PostOrder(T);

    printf("\n————————————————————");
    printf("\n非递归先序遍历:");
    PreOrder2(T);

    printf("\n非递归中序遍历:");
    InOrder2(T);

    printf("\n非递归后序遍历:");
    PostOrder2(T);

    printf("\n————————————————————");
    printf("\n非递归层次遍历:");
    LevelOrder(T);

    return 0;
}

程序测试:


输入:ABD#G###CEH###F##



参考文章:

1、点此链接 (这篇文章写的很用心,博主把栈和队列的相关操作都自己写出来了,值得学习)

2、点此链接 (他用了两种方法,第二种方法中结构体的申明、初始化,容器的使用)

3、点此链接 (二叉树相关的操作实现)


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值