二叉樹的非遞歸遍歷C實現

#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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章