#include<stdio.h>
#include<stdlib.h>
#define maxsize 100
#define StackSize 30 /*假定預分配的棧空間最多爲30*/
typedef struct TNode{
char data;
struct TNode *lchild,*rchild;
}TNode,*Tree;
typedef struct
{
Tree data[maxsize];
int top;
}Stack;//定義棧 因爲要非遞歸遍歷 要藉助棧來實現
typedef Tree SDataType; /*棧的元素類型設爲整型*/
//棧開始定義方法
void InitStack(Stack *S) /*初始棧*/
{ S->top=-1;
}
int StackEmpty(Stack *S) /*判棧空*/
{return S->top==-1;
}
int StackFull(Stack *S) /*判棧滿*/
{return S->top==StackSize-1;
}
void Push(Stack *S, SDataType x) /*進棧*/
{if(StackFull(S))
printf("棧已滿\n"); /*上溢退出*/
else S->data[++S->top]=x; /*棧頂指針加1後將x進棧*/
}
SDataType Pop(Stack *S) /*出棧*/
{if (StackEmpty(S))
printf("Stack underflow"); /*下溢退出*/
else return S->data[S->top--]; /*棧頂指針返回後將棧頂指針減1*/
}
SDataType StackTop(Stack *S) /*取棧頂元素*/
{if (StackEmpty(S))
printf("棧已空\n");
return S->data[S->top];
}
//////////////////////////////////////棧結束
//先序遍歷非遞歸算法1
void preorder_unrecursion_traverse(Tree T)
{
Stack *S;
S=(Stack *)malloc(sizeof(Stack)*StackSize);
Tree p;
InitStack(S);Push(S,T); /*根指針進棧*/
while(!StackEmpty(S)) {
while(p=StackTop(S)) {
printf("%3c",p->data); /*訪問入棧結點的數據域*/
Push(S,p->lchild); /*向左走到盡頭*/
}
p=Pop(S); /*空指針退棧*/
if(!StackEmpty(S)){ /*輸出結點,向右一步*/
p=Pop(S);
/* printf("%3c",p->data); */
Push(S,p->rchild);
}
}
free(S);
}//PreOrderUnrec
//先序遍歷非遞歸算法2
void preorder_unrecursion_traverse2(Tree p)
{
if(!p) return;
Stack *s;
Tree t;
s=(Stack *)malloc(sizeof(Stack)*StackSize);
InitStack(s);
Push(s,p);
while(!StackEmpty(s))
{
t=StackTop(s);
printf("%c\n",t->data);
Pop(s);
if(t->rchild) Push(s,t->rchild);
if(t->lchild) Push(s,t->lchild);
}
free(s);
}
//中序遍歷非遞歸算法
void inorder_unrecursion_traverse(Tree T)
{
Stack *S;
S=(Stack *)malloc(sizeof(Stack)*StackSize);
Tree p=T;
InitStack(S);
while(!StackEmpty(S)||p) {
if(p){
Push(S,p); /*向左走到盡頭*/
p=p->lchild;
}else { /*輸出結點,向右一步*/
p= Pop(S);
printf("%3c",p->data);
p=p->rchild;
}
}
free(S);
}//PreOrderUnrec
void post_unrecursion_traverse(Tree root) //非遞歸後序遍歷
{ Stack *s;
s=(Stack *)malloc(sizeof(Stack)*StackSize);
InitStack(s);
Tree cur; //當前結點
Tree pre=NULL; //前一次訪問的結點
Push(s,root);
while(!StackEmpty(s)){
cur=StackTop(s);
if((cur->lchild==NULL&&cur->rchild==NULL)||(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild))){
printf("%3c",cur->data); //如果當前結點沒有孩子結點或者孩子節點都已被訪問過
Pop(s);
pre=cur;
}else
{
if(cur->rchild!=NULL)
Push(s,cur->rchild);
if(cur->lchild!=NULL)
Push(s,cur->lchild);
}
}
}
//初始化二叉樹
Tree create_tree(void){
Tree T;
char ch;
scanf("%c",&ch);
if(ch=='#')
T=NULL;
else {
if(!(T=(TNode*)malloc(sizeof(TNode))))
exit(-2);
T->data=ch;
T->lchild=create_tree();
T->rchild=create_tree();
}
return T;
}
void show_menu(){
printf("\t\t\t****二叉樹簡單算法****\n");
printf("\t\t\t~~~~~~~~~~~~~~~~~~~~~\n");
printf("\t\t\t#1. 先序非遞歸遍歷 #\n");
printf("\t\t\t#2. 中序非遞歸遍歷 #\n");
printf("\t\t\t#3. 後序非遞歸遍歷 #\n");
printf("\t\t\t#4. 先序非遞歸遍歷2 #\n");
}
int main(int argc, char* argv[])
{
int a;
Tree T,p,q;
int t,l,d,h,m,i;
char ch;
printf("\t\t\t***創建二叉樹****\n");
printf("請輸入樹的各元素,用#表示空節點\n");
T=create_tree();
while(1){
show_menu();
printf("請您選擇(0-6):");
scanf("%d",&t);
switch(t){
case 1:
printf("◎先序非遞歸遍歷:");
preorder_unrecursion_traverse(T);
printf("\n");
break;
case 2:
printf("◎中序非遞歸遍歷:");
inorder_unrecursion_traverse(T);
printf("\n");
break;
case 3:
printf("◎後序非遞歸遍歷:");
post_unrecursion_traverse(T);
printf("\n");
break;
case 4:
printf("◎先序非遞歸遍歷2:");
preorder_unrecursion_traverse2(T);
printf("\n");
break;
default:
printf(" ※輸入出錯!!!請重輸:\n");
}
}
scanf("%d",&a);
return 0;
}