欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据结构——C语言二叉树的非递归遍历的实现

程序员文章站 2022-06-07 07:54:27
...

先序遍历

  • 先序遍历的思想是当栈不为空时就进行弹栈,并将数据输出,记得在每弹一个栈之后要进行两次压栈(这时候要判断其左右孩子是否为空,为空就不压),要注意的是这两次压栈是先压右孩子,再压左孩子,因为栈的先进后出原则。
void preord1(Bitree t){//先序遍历
    stack s;
    Bitree p;
    initstack(s);
    push(s,t);
    while(s.top!=s.base){
        while(gettop(s,p)&&p){
            pop(s,p);
            printf("%c",p->data);
            if(p->rchild!=NULL){
                push(s,p->rchild);
            }
            if(p->lchild!=NULL){
                push(s,p->lchild);
            }
        }
    }
}

中序遍历

  • 中序遍历的大概思想是先一直向左压栈到头(空也压),然后每弹一个栈就转右,转右后再进行压左孩子的循环。
    数据结构——C语言二叉树的非递归遍历的实现
void inordl(Bitree t){//中序遍历
    stack s;
    Bitree p;
    initstack(s);
    push(s,t);
    while(s.top!=s.base){
        while(gettop(s,p)&&p){
            push(s,p->lchild);
        }
        pop(s,p);
        if(s.top!=s.base){
            pop(s,p);
            printf("%c",p->data);
            push(s,p->rchild);
        }
    }
}

后序遍历

  • 用一个数组对其进行标记,只有当标记为1的时候才对其进行输出。
void posord1(Bitree t){//后序遍历
   int tag[100];
   int top=0;
   stack s;
   Bitree p;
   initstack(s);
   p=t;
   do{
       while(p){//扫描左子树
           top++;
           push(s,p);
           p=p->lchild;
           tag[top]=0;
       }
       while((s.top!=s.base)&&tag[top]==1){//p所指向的结点没有左子树或左子树已经访问过了
           pop(s,p);
           printf("%c",p->data);
           top--;
       }
       if(s.top!=s.base){
           gettop(s,p);
           p=p->rchild;
           tag[top]=1;
       }
       else{
           break;
       }
   }while(p||(s.top!=s.base));

输入
数据结构——C语言二叉树的非递归遍历的实现
输出
数据结构——C语言二叉树的非递归遍历的实现
代码

#include<stdio.h>
#include<stdlib.h>

#define m 100

typedef char ElemType;
typedef struct Binodes{
    ElemType data;
    struct Binodes *lchild,*rchild;
}Nodes,*Bitree;
typedef Bitree sselemtype;  //别名的别名,有利于后续的更改
typedef struct stack{
    sselemtype *top,*base;
    int stacksize;
}stack;

int initstack(stack &s){
    s.base=(sselemtype *)malloc(m*sizeof(sselemtype));
    if(s.base==NULL){
        exit(-1);
    }
    s.top=s.base;
    s.stacksize=m;
    return 1;
}

int push(stack &s,sselemtype e){
    if(s.top-s.base>=s.stacksize){
        return 0;
    }
    *s.top++=e;
    return 1;
}
int pop(stack &s,sselemtype &e){
    if(s.top==s.base){
        return 0;
    }
    e=*--s.top;
    return 1;
}

int CreateTree(Bitree &T){//创建树
    ElemType value;
    scanf("%c",&value);
    if(value==' '){
        T=NULL;
    }
    else{
        T=(Nodes*)malloc(sizeof(Nodes));
        if(!T){
            exit(-2);
        }
        T->data=value;
        CreateTree(T->lchild);
        CreateTree(T->rchild);
    }
}
int gettop(stack s,Bitree &e){//读栈顶
    if(s.top==s.base){
        return 0;
    }
    e=*(s.top-1);
    return 1;
}
void preord1(Bitree t){//先序遍历
    stack s;
    Bitree p;
    initstack(s);
    push(s,t);
    while(s.top!=s.base){
        while(gettop(s,p)&&p){
            pop(s,p);
            printf("%c",p->data);
            if(p->rchild!=NULL){
                push(s,p->rchild);
            }
            if(p->lchild!=NULL){
                push(s,p->lchild);
            }
        }
    }
}
void inordl(Bitree t){//中序遍历
    stack s;
    Bitree p;
    initstack(s);
    push(s,t);
    while(s.top!=s.base){
        while(gettop(s,p)&&p){
            push(s,p->lchild);
        }
        pop(s,p);
        if(s.top!=s.base){
            pop(s,p);
            printf("%c",p->data);
            push(s,p->rchild);
        }
    }
}
void posord1(Bitree t){//后序遍历
    int tag[100];
    int top=0;
    stack s;
    Bitree p;
    initstack(s);
    p=t;
    do{
        while(p){//扫描左子树
            top++;
            push(s,p);
            p=p->lchild;
            tag[top]=0;
        }
        while((s.top!=s.base)&&tag[top]==1){//p所指向的结点没有左子树或左子树已经访问过了
            pop(s,p);
            printf("%c",p->data);
            top--;
        }
        if(s.top!=s.base){
            gettop(s,p);
            p=p->rchild;
            tag[top]=1;
        }
        else{
            break;
        }
    }while(p||(s.top!=s.base));
}

int main()
{
    Bitree T;
    CreateTree(T);
    printf("非递归的先根遍历顺序为:\n");
    preord1(T);
    printf("\n非递归的中根遍历顺序为:\n");
    inordl(T);
    printf("\n非递归的后根遍历顺序为:\n");
    posord1(T);
    return 0;
}