非递归遍历二叉树

               DataStruture is the basis of programming,and then it is often mentioned during the interview to test how much a computer scientice graduate has mastered.Now I make a summary about it.  ---------Noted by me


数据结构是程序设计的基础,面试时往往成为考核的重点,现总结归纳一下非递归遍历二叉树算法(包括前序、中序、后序):


#include<stdio.h>
#include<stdlib.h>
# define  OK 1
# define  OVERFLOW -1
# define  ERROR 0
# define  TRUE 1
# define  FALSE 0

# define  Maxsize 100

typedef char ElemType;
typedef struct BiTNode{//结点结构
    ElemType data;//数据元素
    struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;


typedef struct{
    BiTree *base;
    BiTree *top;
}SqStack;

void InitStack(SqStack &S){
  //S.base=(BiTree*)malloc(20*sizeof(BiTree));
    S.base=new BiTree[Maxsize];
    if(!S.base)exit(-2);
    S.top=S.base;
}
void Push(SqStack &S,BiTree p){
    *S.top++=p;
}
void Pop(SqStack &S,BiTree &p){
    p=*--S.top;
}
int StackEmpty(SqStack S){
    if(S.top==S.base)return 1;
    return 0;
}
BiTree GetTop(SqStack S){
    return *(S.top-1);
}


void PreOrderTraverse(BiTree T){//先序遍历二叉树算法
    if(T){
        printf("%c",T->data);//访问结点
        PreOrderTraverse(T->lchild);//遍历左子树
        PreOrderTraverse(T->rchild);//遍历右子树
    }
}


void InOrderTraverse(BiTree T){//中序遍历二叉树算法
    if(T){
        InOrderTraverse(T->lchild);//遍历左子树算法
        printf("%c",T->data);//访问结点
        InOrderTraverse(T->rchild);//遍历右子树
    }
}

void PostOrderTraverse(BiTree T){//后序遍历二叉树算法
    if(T){
        PostOrderTraverse(T->lchild);//遍历左子树
        PostOrderTraverse(T->rchild);//遍历右子树
        printf("%c",T->data);//访问结点
    }
}

int CreateBiTree(BiTree &T){
    ElemType ch;
    scanf("%c",&ch);
    if(ch==' ')T=NULL;
    else{
        if(!(T=new BiTNode))exit(OVERFLOW);
        T->data=ch;//生成根结点
        CreateBiTree(T->lchild);//构造左子树
        CreateBiTree(T->rchild);//构造右子树
    }
    return OK;  
}//CreateBiTree



先序遍历的非递归算法:

(1)二叉树的根结点进栈。
(2)当栈不空循环:当栈顶元素非空时访问它,并将该结点的左子树的根结点进栈,直到栈顶元素为空,并将空指针出栈;如果栈不空,栈顶元素出栈,并将该结点的右子树的根结点进栈。如此操作,直到栈空为止。

void PreOrder_Nonrecursive(BiTree T){//先序遍历的非递归算法
    SqStack S;
    BiTree p;
    InitStack(S);
    Push(S,T);//根指针进栈
    while(!StackEmpty(S)){
        while(GetTop(S)){
            printf("%c",GetTop(S)->data);//访问结点,向左一步
            Push(S,GetTop(S)->lchild);
        }//向左走到尽头
        Pop(S,p);//空指针出栈
        if(!StackEmpty(S)){//向右一步
            Pop(S,p);
            Push(S,p->rchild);
        }
    }//while
}//PreOrder_Nonrecursive


中序遍历的非递归算法:

(1)二叉树的根结点进栈。
(2)当栈不空循环:当栈顶元素非空时,将该结点的左子树的根结点进栈,直到栈顶元素为空,并将空指针出栈;如果栈不空,栈顶元素出栈,访问该元素,并将该结点的右子树的根结点进栈。如此操作,直到栈空为止。

void InOrder_Nonrecursive(BiTree T){//中序遍历的非递归算法
    SqStack S;
    BiTree p;
    InitStack(S);
    Push(S,T);//根指针进栈
    while(!StackEmpty(S)){
        while(GetTop(S))Push(S,GetTop(S)->lchild);//向左走到尽头
        Pop(S,p);//空指针出栈
        if(!StackEmpty(S)){//访问结点,向右一步
            Pop(S,p);
            printf("%c",p->data);
            Push(S,p->rchild);
        }//if
    }//while
}//InOrder_Nonrecursive


void main(){
    BiTree T;
    CreateBiTree(T);
    PreOrderTraverse(T);
    printf("\n");
    InOrderTraverse(T);
    printf("\n");
    PostOrderTraverse(T);
    printf("\n");
    PreOrder_Nonrecursive(T);
    printf("\n");
    InOrder_Nonrecursive(T);
    printf("\n");
}

--------------------------------------------------------------------------------------------------------------------------------------------------

#include<stdio.h>
#include<stdlib.h>
# define  OK 1
# define  OVERFLOW -1
# define  ERROR 0
# define  TRUE 1
# define  FALSE 0

# define  Maxsize 100

typedef char ElemType;
typedef struct BiTNode{//结点结构
    ElemType data;//数据元素
    struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;

typedef struct PMType{
    BiTree ptr;
    int mark;//mark=0表示刚刚访问此结点,mark=1表示左子树处理结束返回,mark=2表示右子树处理结束返回。
}PMType;


typedef struct{
    PMType *base;
    PMType *top;
}SqStack;

void InitStack(SqStack &S){
  //S.base=(BiTree*)malloc(20*sizeof(BiTree));
    S.base=new PMType[Maxsize];
    if(!S.base)exit(-2);
    S.top=S.base;
}
void Push(SqStack &S,PMType p){
    *S.top++=p;
}
void Pop(SqStack &S,PMType &p){
    p=*--S.top;
}
int StackEmpty(SqStack S){
    if(S.top==S.base)return 1;
    return 0;
}
PMType GetTop(SqStack S){
    return *(S.top-1);
}


void PreOrderTraverse(BiTree T){//先序遍历二叉树算法
    if(T){
        printf("%c",T->data);//访问结点
        PreOrderTraverse(T->lchild);//遍历左子树
        PreOrderTraverse(T->rchild);//遍历右子树
    }
}


void InOrderTraverse(BiTree T){//中序遍历二叉树算法
    if(T){
        InOrderTraverse(T->lchild);//遍历左子树算法
        printf("%c",T->data);//访问结点
        InOrderTraverse(T->rchild);//遍历右子树
    }
}


void PostOrderTraverse(BiTree T){//后序遍历二叉树算法
    if(T){
        PostOrderTraverse(T->lchild);//遍历左子树
        PostOrderTraverse(T->rchild);//遍历右子树
        printf("%c",T->data);//访问结点
    }
}

int CreateBiTree(BiTree &T){
    ElemType ch;
    scanf("%c",&ch);
    if(ch==' ')T=NULL;
    else{
        if(!(T=new BiTNode))exit(OVERFLOW);
        T->data=ch;//生成根结点
        CreateBiTree(T->lchild);//构造左子树
        CreateBiTree(T->rchild);//构造右子树
    }
    return OK;  
}//CreateBiTree



后序遍历的非递归算法:

与先序遍历和中序遍历的非递归情况有所不同,在后序遍历二叉树的过程中,对一个结点访问之前,要两次经过这个结点,第一次是由该结点找到其左子树,对其左子树进行遍历,遍历完成后,返回到该结点。第二次是由该结点找到其右子树,对其右子树进行遍历,遍历完成后,返回该结点,此时才能访问该结点。

所以,在后序遍历的非递归算法中,同样需要一个栈,而且为了区分某一个结点是第一次进栈还是第二次进栈,在栈结构中还得设置一个标志域来区分。其栈结点的定义如下:

typedef struct PMType{
    BiTree ptr;
    int mark;//mark=0表示刚刚访问此结点,mark=1表示左子树处理结束返回,mark=2表示右子树处理结束返回。
}PMType;

void PostOrder_Stack(BiTree T){//后序遍历的非递归算法
    PMType a;
    SqStack S;
    InitStack(S);//S的元素为PMType类型
    a.ptr=T;
    a.mark=0;
    Push(S,a);//根结点入栈
    while(!StackEmpty(S)){
        Pop(S,a);
        switch(a.mark){
        case 0:a.mark=1;Push(S,a);//修改mark域
            if(a.ptr->lchild) {a.ptr=a.ptr->lchild;a.mark=0;Push(S,a);} //访问左子树
            break;
        case 1:a.mark=2;Push(S,a); //修改mark域
            if(a.ptr->rchild) {a.ptr=a.ptr->rchild;a.mark=0;Push(S,a);}//访问右子树
            break;
        case 2:printf("%c",a.ptr->data); //访问结点,返回
            break;
        }
    }//while
}//PostOrder_Stack


void main(){
    BiTree T;
    CreateBiTree(T);
    PreOrderTraverse(T);
    printf("\n");
    InOrderTraverse(T);
    printf("\n");
    PostOrderTraverse(T);
    printf("\n");
    PostOrder_Stack(T);    
    printf("\n");
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值