1. 程式人生 > >資料結構----二叉樹遍歷的非遞迴演算法實現

資料結構----二叉樹遍歷的非遞迴演算法實現

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
  
#define OK 0;  
#define ERROR -1  
#define OVERFLOW -2  
#define YES 1  
#define NO 0  
  
#define STACK_INIT_SIZE 100  
#define STACK_INCREMENT 10  
  
  
typedef int Status;  
typedef int TElemType;  
  
  
//二叉樹的順序儲存結構  
#define MaxTreeSize 101  
typedef TElemType BiTreeArr[MaxTreeSize];  
BiTreeArr bt;  
  
//二叉樹的鏈式儲存結構  
typedef struct BiTNode  
{  
    TElemType data;  
    struct BiTNode *lchild,*rchild;  
}BiTNode,*BiTreeLk;  
  
  
typedef BiTreeLk SElemType;  
  
//@@@@@@@@@@@@@@@@@@@  
//棧的資料結構部分開始  
  
typedef struct  
{  
 SElemType *base;  
 SElemType *top;  
 int stacksize;  
}SqStack;  
  
//初始化棧  
Status InitStack(SqStack &Stack)  
{  
 Stack.base = (SElemType *)malloc(sizeof(SElemType)*STACK_INIT_SIZE);  
 if(!Stack.base) exit(OVERFLOW);  
 Stack.top = Stack.base;  
 Stack.stacksize = STACK_INIT_SIZE;
 return OK;
}  
  
//得到棧頂元素  
Status GetTop(SqStack &Stack,SElemType &e)  
{  
 if(Stack.top==Stack.base)  
  return ERROR;  
  e = *(Stack.top-1);  
  return OK;  
}  
  
//壓棧  
Status Push(SqStack &Stack,SElemType e)  
{  
 if(Stack.top-Stack.base>=Stack.stacksize)  
 {  
  Stack.base= (SElemType *)realloc(Stack.base, sizeof(SElemType)*(Stack.stacksize+STACK_INCREMENT));  
  if(!Stack.base)  return ERROR;  
  Stack.top = Stack.base+Stack.stacksize;  
  Stack.stacksize += STACK_INCREMENT;  
 }  
 *Stack.top++ = e;  
 return OK;  
}  
  
//出棧  
Status Pop(SqStack &Stack,SElemType &e)  
{  
 if(Stack.top==Stack.base)  return ERROR;  
 Stack.top--;  
 e = *Stack.top; return OK;  
}  
  
  
Status StackEmpty(SqStack &Stack)  
{  
    if(Stack.base == Stack.top)  
        return YES;  
    return NO;  
}  
  
//棧的資料結構部分結束  
//@@@@@@@@@@@@@@@@@@@@@@@@@@@  
  
Status Visit(TElemType data)  
{  
    if(&data==NULL)  
    {  
        return ERROR;  
    }  
    else  
    {  
        printf("    %d",data);  
        return OK;  
    }  
}  
  
//採用遞迴演算法的先序、中序和後序遍歷演算法  
//先序遞迴便利演算法  
Status PreOrderTraverse( BiTreeLk T, Status(*Visit)(TElemType) )  
{  
    if(T)  
    {  
        if(Visit(T->data))  
            if(PreOrderTraverse(T->lchild, Visit))  
                if (PreOrderTraverse(T->rchild, Visit))  
                    return OK;  
        return ERROR;  
    }  
   else  
        return OK;  
}  
//中序遞迴遍歷演算法  
Status InOrderTraverse( BiTreeLk T, Status(*Visit)(TElemType) )  
{  
    if(T)  
    {  
        if(PreOrderTraverse(T->lchild, Visit))  
            if(Visit(T->data))  
                if (PreOrderTraverse(T->rchild, Visit))  
                    return OK;  
        return ERROR;  
    }  
   else  
        return OK;  
}  
//後序遞迴遍歷演算法  
Status PostOrderTraverse( BiTreeLk T, Status(*Visit)(TElemType) )  
{  
    if(T)  
    {  
        if(PreOrderTraverse(T->lchild, Visit))  
            if (PreOrderTraverse(T->rchild, Visit))  
                if(Visit(T->data))  
                    return OK;  
        return ERROR;  
    }  
   else  
        return OK;  
}  
  
//非遞迴的二叉樹中序遍歷演算法  
//大體的思路是儲存在遍歷樹時走過的路徑,節點彈出的順序即為節點訪問的順序  
Status InOrderTraverse1(BiTreeLk T,Status(*Visit)(TElemType e))  
{  
    SqStack Stack;  
    BiTreeLk p;  
    InitStack(Stack);               //初始化一個棧  
    Push(Stack,T);                  //將根節點壓入棧中  
    while(!StackEmpty(Stack))       //滿足棧不空的條件  
    {  
        while(GetTop(Stack,p)&&p)   //獲取棧的最上面的指標  
            Push(Stack,p->lchild);  //向左走到盡頭,將這條線路上的點都壓入棧中  
        Pop(Stack,p);               //彈出入棧的空指標  
        if(!StackEmpty(Stack))      //如果棧不為空  
        {  
            Pop(Stack,p);           //彈出一個節點指標  
            if(
!Visit(p->data)) //訪問這個節點  
                return ERROR;  
            Push(Stack,p->rchild);  //將其右節點入棧  
        }  
    }  
return OK;
}  
  
//非遞迴的二叉樹中序遍歷演算法  
Status InOrderTraverse2(BiTreeLk T, Status (*Visit)(TElemType e))  
{  


    SqStack Stack;  
    InitStack(Stack);  
    BiTreeLk p = T;  
    while(p||!StackEmpty(Stack))  
    {  
        if(p)  
        {  
            Push(Stack,p);  
            p = p->lchild;  
        }  
        else  
        {  
            Pop(Stack,p);  
            if(!Visit(p->data))  
                return ERROR;  
            p = p->rchild;  
        }  
    }  
    return OK;  
}  
  
Status CreateBitreeLk(BiTreeLk &T)  
{  
    char ch=' ';  
    scanf("%c",ch);  
    if(ch==' ')  
        T = NULL;  
    else  
    {  
        if(!(T=(BiTreeLk)malloc(sizeof(BiTNode))))  
            return ERROR;  
        T->data = ch;  
        CreateBitreeLk(T->lchild);  
        CreateBitreeLk(T->rchild);  
    }  
    return OK;  
}  
  
   
  
int main()  
{  
    //Todo functions is here  
    //test the data structure above using the sampes of " A  B C @ @ D E @ g @ @ f @ @ @ "  
    //'@' denote the empty character  
    BiTreeLk T;  
    CreateBitreeLk(T);  
    InOrderTraverse1(T,Visit);  
    return 0;  
}