后序非递归遍历二叉树

原文链接:http://blog.csdn.net/zhouzixin053/article/details/24129129

非递归后序遍历算法思想

  后序遍历的非递归算法中节点的进栈次数是两个,即每个节点都要进栈两次,第二次退栈的时候才访问节点。
  第一次进栈时,在遍历左子树的过程中将”根”节点进栈,待左子树访问完后,回溯的节点退栈,即退出这个”根”节点,但不能立即访问,只能借助于这个”根”去找该”根”的右子树,并遍历这棵右子树,直到该右子树全部遍历以后,再退出该”根”节点,并访问它。
  所以为了记录节点是第一次还是第二次进栈,就在堆栈数据元素的结构中增加一个数据项:进栈标志。
  (1)当节点非空时或堆栈非空时,执行(2),否则结束算法;
  (2)当节点指针非空时,节点的进栈标志设为false,节点指针及进栈标志进栈,然后将节点指向进栈节点的左子树的根,重复(2),知道指针为空(最后一个进栈的是最左子树),节点指针为空时,转(3);
  (3)堆栈非空时,从堆栈中退出一个节点的指针。如果退出的节点的进栈标志为true,说明该节点是第二次退栈,访问该接点,并将指针强制设为空,准备下一次退栈,并转(3),如果进栈标志为false,说明该节点是第一次退栈,将进栈标志设为true,然后将该节点指针及进栈标志进栈,再将指针指向它的右子树,转(1)。

代码实现

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

typedef char EType;   

struct BinaryTreeNode  
{  
    EType data;  
    struct BinaryTreeNode *LChild;  
    struct BinaryTreeNode *RChild;  
};  
typedef BinaryTreeNode BinaryTree;  

typedef struct SType  
{  
    BinaryTreeNode *ptr;  
    bool status;//进栈标志  
}SType;  

typedef struct Stack  
{  
    SType *element;  
    int top;  
    int MaxSize;  
}Stack;  

void CreatStack(Stack &S,int MaxStackSize);  
bool IsEmpty(Stack &S);  
bool IsFull(Stack &S);  
bool GetTop(Stack &S,SType &result);  
bool Pop(Stack &S,SType &result);  
bool Push(Stack &S,SType &x);  
void CreatBiTree(BinaryTreeNode **BT);  
void PostOrderNoRecursive(BinaryTreeNode *BT);  

int main()  
{  
    BinaryTreeNode *BT = NULL;  
    CreatBiTree(&BT);  
    printf("后序遍历二叉树非递归算法输出为:");  
    PostOrderNoRecursive(BT);  
    printf("\n");  
    return 0;  
}  

void CreatStack(Stack &S,int MaxStackSize)  
{  
    S.MaxSize = MaxStackSize;  
    S.element = new SType[S.MaxSize];  
    S.top = -1;  
}  

bool IsEmpty(Stack &S)  
{  
    if(S.top == -1)  
        return true;  
    return false;  
}  

bool IsFull(Stack &S)  
{  
    if(S.top >= S.MaxSize-1)  
        return true;  
    return false;  
}  

bool GetTop(Stack &S,SType &result)  
{  
    if(IsEmpty(S))  
        return false;  
    result = S.element[S.top];  
    return true;  
}  

bool Pop(Stack &S,SType &result)  
{  
    if(IsEmpty(S))  
        return false;  
    result = S.element[S.top];  
    S.top--;  
    return true;  
}  

bool Push(Stack &S,SType &x)  
{  
    if(IsFull(S))  
        return false;  
    S.top++;  
    S.element[S.top] = x;  
    return true;  
}  

void CreatBiTree(BinaryTreeNode **BT)  
{  
    EType tem;  

    scanf("%c",&tem);  
    if(' ' == tem)  
    {  
        *BT = NULL;  
    }  
    else  
    {  
        *BT = new BinaryTreeNode;  
        (*BT)->data = tem;  
        CreatBiTree(&(*BT)->LChild);  
        CreatBiTree(&(*BT)->RChild);  
    }  
}  

void PostOrderNoRecursive(BinaryTreeNode *BT)  
{  
    Stack S;  
    SType temp;  
    BinaryTreeNode *p = BT;  
    int MaxStackSize = 50;  
    CreatStack(S,MaxStackSize);  

    while(p || !IsEmpty(S))  
    {  
        if(p)//找最左子树  
        {  
            temp.status = false;//设置该节点是第一次进栈  
            temp.ptr = p;  
            Push(S,temp);  
            p = p->LChild;  
        }  
        else  
        {  
            if(!IsEmpty(S))  /*该判断多余?*/
            {  
                Pop(S,temp);  
                p = temp.ptr;  
                if(temp.status)//若该节点是第二次退栈,就访问,并设置p=0继续退栈  
                {  
                    printf("%c\t",p->data);  
                    p = NULL;  
                }     
                else  
                {  
                    temp.status = true;//设置该节点是第二次进栈  
                    Push(S,temp);  
                    p = p->RChild;//遍历该节点的右子树  
                }  
            }  
        }  
    }  
}  
发布了6 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/dearyangjie/article/details/78266579