1. 程式人生 > >二叉樹非遞迴前序建立與後序遍歷

二叉樹非遞迴前序建立與後序遍歷

建立過程:通過棧來模擬遞迴建立。先將根壓入棧中,然後不斷的加左子樹,遇到空則加右子樹;在開始不斷的加左子樹...一直                     重複下去直到讀取到回車。(建立時不要對傳入的根直接操作,否者最後返回去的東西不對)。

遍歷過程:通過兩個棧來實現。s棧進行遍歷過程,r棧存放結果。因為要後續輸出,所以遍歷是應該為根->右子樹->左子樹。開                    始遍歷,如果節點node不為空這把這個節點放入 s 與 r 中,然後node=node->rchild;如果node為空,則把s棧頂元素                       彈出,node指向彈出元素的右子樹...重複執行直到s棧為空。

參考連結https://www.jianshu.com/p/fff56a761dde

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

typedef char TElemType;
typedef struct BiTNode{     //樹
    TElemType data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

#define STACK_INIT_SIZE 100
#define STACKINCREASE 10
typedef BiTree SElemType;
typedef struct{
    SElemType *base;
    SElemType *top;     //棧頂指標
    int stacksize;      //當前以分配儲存空間
}SqStack;

void InitStack(SqStack &S){
    S.base=NULL;
    S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
    if(!S.base){
        printf("棧分配失敗!\n");
        exit(-1);
    }
    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;
}

void Push(SqStack &S, BiTree &e){        //壓棧
    if(S.top - S.base >= S.stacksize){
        S.base = (SElemType *)realloc(S.base,(STACKINCREASE+STACK_INIT_SIZE)*sizeof(BiTNode));  //棧滿。追加空間
        if(!S.base){
        printf("棧分配失敗!\n");
        exit(-1);
        S.top = S.base+S.stacksize;
        S.stacksize +=STACKINCREASE;
        }
    }
    *(S.top) = e;
    S.top++;
}

BiTree GetTop(SqStack S){       //獲得棧頂元素
    if(S.top == S.base){
        return 0;
    }
    return *(S.top-1);
}

BiTree Pop(SqStack &S){           //出棧
    if(S.top == S.base){
            return 0;
    }
    S.top--;
    return *S.top;
}

int Empty(SqStack S){
    if(S.top == S.base){ //判斷棧是否為空 1為空
        return 1;
    }
    return 0;
}
    
void CreatBiTree(BiTree &P){
    //先序建立二叉樹,空格表示空樹
    char tmp;
    scanf("%c",&tmp);
    if(tmp==' '){
        P=NULL;
        printf("This is a empty tree!\n");
        return ;
    }
    P=(BiTree)malloc(sizeof(BiTNode));
    BiTree T=P;
    T->data=tmp;
    SqStack s;
    InitStack(s);
    Push(s,T);
    while(!Empty(s)){
        while(scanf("%c",&tmp)){
        T=GetTop(s);
        if(tmp == ' '){
            T->lchild = NULL;
            break;
        }
        T->lchild = (BiTree)malloc(sizeof(BiTNode));
        T->lchild->data = tmp;
        Push(s,T->lchild);
        }
        while(scanf("%c",&tmp)){
            if(tmp == '\n') return ;
            T=GetTop(s);
            if(tmp!=' '){
                T->rchild = (BiTree)malloc(sizeof(BiTNode));
                T->rchild->data = tmp;
                BiTree a=Pop(s);
                Push(s,T->rchild);

                break;
            }
            T->rchild = NULL;
            T=Pop(s);
        }
    }
}

void Print(TElemType e){
    //列印字元
   putchar(e);
}

void PostOrderTraverse(BiTree T,void (*visit)(TElemType e)){
    //非遞迴實現後序遍歷
    SqStack s,r;
    InitStack(s);
    InitStack(r);
    BiTree p=T;
    while(!Empty(s) || p){
        if(p){
            Push(s,p);
            Push(r,p);
            p=p->rchild;
        }else{
            p = Pop(s);
            p=p->lchild;
        }
    }
    while(!Empty(r)){
        p=Pop(r);
        visit(p->data);
    }
}

int main()
{
    BiTree t;
    //t=(BiTree)malloc(sizeof(BiTNode));
    CreatBiTree(t);
    printf("後續遍歷:\n");
    PostOrderTraverse(t,Print);
    printf("\n\n");

    return 0;
}