建立過程:通過棧來模擬遞歸建立。先將根壓入棧中,然後不斷的加左子樹,遇到空則加右子樹;在開始不斷的加左子樹...一直 重複下去直到讀取到回車。(創建時不要對傳入的根直接操作,否者最後返回去的東西不對)。
遍歷過程:通過兩個棧來實現。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;
}