二叉树三种非递归遍历

好久没刷题了。。。发个实验课的东西充数吧

#include <iostream>
#include<cstdio>
#define prt cout<<"请输入二叉树:"
using namespace std;
struct node{
    char c;     // 字符数据
    node *l,*r;  // 左右子树指针
    node(char cc){ // 构造函数
        c=cc;
        l=r=NULL;
    }
};
bool checkerror(char str[]); // 声明查错函数
node *creat(char str[]){    // 创建新树函数
    node *root,*sta[100];   // 定义根节点指针,指针栈
    node **p=&root;     // 定义指向指针的指针p,并初始化指向根指针
    int i=0,top=0;
    char c;
    while(c=str[i++]){  // 遍历输入的字符串
        if(c=='('){  // 若遇见左括号,说明当前节点有儿子
           sta[++top]=*p; // 将p指向的指针入栈
           p=&(sta[top]->l); // p指向栈顶指针的左儿子指针
        }
        else if(c==','){ // 若遇见逗号,说明后面要处理的是父节点的右儿子
            p=&(sta[top]->r); // p指向栈顶指针的右儿子指针
        }
        else if(c==')'){ // 若遇见右括号,退栈
            top--;
        }
        else{            // 若遇见字母字符
            *p=new node(c); // 为p当前指向的指针申请空间并填充数据
        }
    }
    return root;        // 返回根节点指针
}
void preorder(node *root){ // 先序遍历函数
    node *p,*sta[200];  // 定义指针栈
    int top=0;      // sta[0]不存数据,作为栈空的标志
    sta[++top]=root; // 将根节点入栈
    while(top){     // 当栈不空时进入循环
        p=sta[top--];  // 取出栈顶元素并退栈,之后先沿其左子树遍历
        while(p!=NULL){ // 若p不为空
            cout<<p->c<<' '; // 输出节点数据
            sta[++top]=p->r; // 将当前节点的右儿子指针入栈
            p=p->l;         // p指向其左儿子
        }
    }
    cout<<endl;
}
void inorder(node *root){ // 中序遍历函数
    node *p=root,*sta[200];
    int top=0;
    do{
        while(p!=NULL){
            sta[++top]=p;
            p=p->l;
        }
        p=sta[top--];
        cout<<p->c<<' ';
        p=p->r;
    }while(top||p!=NULL);
    cout<<endl;
}
void postorder(node *root){ // 后序遍历函数
    node *p=root,*sta[200];
    int top=0;
    do{
        while(p!=NULL){
            sta[++top]=p;
            p=p->l;
        }
        while(top&&sta[top]->r==p){
            p=sta[top--];
            cout<<p->c<<' ';
        }
        p=top?sta[top]->r:NULL;
    }while(top);
    cout<<endl;
}
void bfs(node *root){ // 层次遍历函数
    node *p,*que[200];
    int l,r; l=r=0;
    que[r++]=root;
    while(l<r){
        p=que[l++];
        cout<<p->c<<' ';
        if(p->l) que[r++]=p->l;
        if(p->r) que[r++]=p->r;
        delete p;       // 释放空间
    }
    cout<<endl;
}
int main(){
    char str[200];
    cout<<"二叉树测试程序,输入Ctrl+Z退出\n";
    while(prt,gets(str)){    // prt宏为输出提示信息
        if(checkerror(str)) continue; //若输入不合法,不做处理
        node *root=creat(str);
        cout<<"  先序遍历:"; preorder(root);
        cout<<"  中序遍历:"; inorder(root);
        cout<<"  后序遍历:"; postorder(root);
        cout<<"  层次遍历:"; bfs(root); // 在层次遍历的同时释放内存
        cout<<endl;
    }
    return 0;
}
bool checkerror(char str[]){    // 查错函数
    int i=0,tag=3,d=0,vis[200]; // vis[]记录某节点儿子个数,tag记录前一字符的类型,
    char c;                     // 1:'(' 2:')' 3:',' 0:普通字母
    vis[0]=1;
    while(c=str[i++]){
        if(c=='('){
            if(tag!=0) break;
            tag=1; vis[++d]=0;
        }
        else if(c==')'){
            if(tag==1) break;
            tag=2; d--;
        }
        else if(c==','){
            if(tag==3) break;
            tag=3; vis[d]++;
        }
        else{
            if(tag==0||tag==2) break;
            tag=0;
        }                        //以上为检查字符串格式是否合法
        if(d<0||vis[d]>1) break; //通过层数与节点儿子个数,检查逻辑是否合法
    }
    if(i==1||d>0||c!=0){
        cout<<"  输入格式错误!请重新输入!\n\n";
        return 1;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值