【我的算法笔记】二叉树的创建、二叉树的遍历(递归、非递归)


前言

本篇文章主要包括二叉树的创建以及二叉树的前序、中序、后序遍历的递归算法以及前序、中序、后序、层次遍历的非递归算法


  • 树的结构体定义

typedef struct node{
    char data;
    struct node *lchild,*rchild;
}*BiTree;
  • 二叉树的创建(先序递归) 

//递归建立二叉树(先序遍历)
void CreatBiTree(BiTree &T){
    char c;
    cin>>c;
    if(c=='0'){
        T=NULL;
    }else{
        T=new node;
        T->data=c;
        CreatBiTree(T->lchild);
        CreatBiTree(T->rchild);
    }
}
  •  二叉树的先序遍历(递归)

//先序遍历递归
void PreOrder(BiTree T){
    if(T!=NULL){
        cout<<T->data<<' ';
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    }
}
  • 二叉树的中序遍历(递归) 

//递归中序遍历
void InOrder(BiTree T){
    if(T!=NULL){
        InOrder(T->lchild);
        cout<<T->data<<' ';
        InOrder(T->rchild);
    }
}
  •  二叉树的后序遍历(递归)

//递归后序遍历算法
void PostOrder(BiTree T){
    if(T!=NULL){
        PostOrder(T->lchild);
        PostOrder(T->rchild);
        cout<<T->data<<' ';
    }
}
  •  二叉树的先序非递归遍历算法1

头文件中要包含#include<stack> 

//非递归先序遍历算法1
void PreOrder1(BiTree T){
    if(T!=NULL){
        stack<BiTree> St;
        BiTree p;
        St.push(T);
        while(!St.empty()){
            p=St.top();
            St.pop();
            cout<<p->data<<' ';
            if(p->rchild!=NULL){
                St.push(p->rchild);
            }
            if(p->lchild!=NULL){
                St.push(p->lchild);
            }
        }
    }
}
  •  二叉树的先序非递归遍历算法2

//非递归先序遍历2
void PreOrder2(BiTree T){
    if(T!=NULL){
        stack<BiTree> St;
        BiTree p=T;
        while(!St.empty()||p!=NULL){
            while(p!=NULL){
                cout<<p->data<<' ';
                St.push(p);
                p=p->lchild;
            }
            if(!St.empty()){
                p=St.top();
                St.pop();
                p=p->rchild;
            }
        }
    }
}
  • 二叉树的中序非递归算法

 与先序非递归遍历算法2的区别仅在于节点值输出的位置不同

//非递归中序遍历
void InOrder1(BiTree T){
    if(T!=NULL){
        stack<BiTree> St;
        BiTree p=T;
        while(!St.empty()||p!=NULL){
            while(p!=NULL){
                St.push(p);
                p=p->lchild;
            }
            if(!St.empty()){
                p=St.top();
                St.pop();
                cout<<p->data<<' ';
                p=p->rchild;
            }
        }
    }
}
  •  二叉树的后序非递归算法1

 需要用到两个栈

//非递归后序遍历算法1
void PostOrder1(BiTree T){
    if(T!=NULL){
        stack<BiTree> St1;
        stack<BiTree> St2;
        BiTree p=NULL;
        St1.push(T);
        while(!St1.empty()){
            p=St1.top();
            St1.pop();
            St2.push(p);
            if(p->lchild!=NULL){
                St1.push(p->lchild);
            }
            if(p->rchild!=NULL){
                St1.push(p->rchild);
            }
        }
        while(!St2.empty()){
            p=St2.top();
            St2.pop();
            cout<<p->data<<' ';
        }
    }
}
  •  二叉树的非递归后序遍历算法2

 这个算法具有一个良好的性质:每当访问到这个节点时,栈中存放的是这个节点的祖先节点。由这个算法可以改写得到其他许多问题的解法。

//非递归后序遍历算法2
void PostOrder2(BiTree T){
    if(T!=NULL){
        stack<BiTree> St;
        BiTree p=T;
        BiTree r=NULL;
        while(p!=NULL||!St.empty()){
            if(p!=NULL){
                St.push(p);
                p=p->lchild;
            }
            else{
                p=St.top();
                if(p->rchild!=NULL&&p->rchild!=r){
                    p=p->rchild;
                }else{
                    p=St.top();
                    St.pop();
                    cout<<p->data<<' ';
                    r=p;
                    p=NULL;
                }
            }
        }
    }
}
  •  二叉树的层次遍历算法

 头文件中要包含#include<queue>

//层次遍历
void LevelOrder(BiTree T){
    queue<BiTree> Q;
    Q.push(T);
    BiTree p;
    while(!Q.empty()){
        p=Q.front();
        Q.pop();
        cout<<p->data<<' ';
        if(p->lchild!=NULL){
            Q.push(p->lchild);
        }
        if(p->rchild!=NULL){
            Q.push(p->rchild);
        }
    }
}

主函数 

int main(){
    system("chcp 65001");//控制输出中文
    BiTree T;
    CreatBiTree(T);
    cout<<"二叉树的先序遍历序列为:";
    PreOrder(T);
    cout<<endl;
    cout<<"二叉树的先序遍历序列为:";
    PreOrder1(T);
    cout<<endl;
    cout<<"二叉树的先序遍历序列为:";
    PreOrder2(T);
    cout<<endl;
    cout<<"二叉树的中序遍历序列为:";
    InOrder(T);
    cout<<endl;
    cout<<"二叉树的中序遍历序列为:";
    InOrder1(T);
    cout<<endl;
    cout<<"二叉树的后序遍历序列为:";
    PostOrder(T);
    cout<<endl;
    cout<<"二叉树的后序遍历序列为:";
    PostOrder1(T);
    cout<<endl;
    cout<<"二叉树的后序遍历序列为:";
    PostOrder2(T);
    cout<<endl;
    cout<<"二叉树的层次遍历序列为:";
    LevelOrder(T);
    cout<<endl;
    return 0;
}

运行结果如下图所示:

上例中建的树如下图所示:

总结

        以上就是这篇文章的全部内容,介绍了二叉树的构建以及遍历。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值