1. 程式人生 > >資料結構--非遞迴遍歷二叉樹(利用輔助棧)

資料結構--非遞迴遍歷二叉樹(利用輔助棧)

#include "StdAfx.h"  
#include <stdio.h>  
#include <stdlib.h>  
/*非遞迴方法前序遍歷二叉樹,利用輔助棧(指標陣列實現)。由於對指標不是很熟悉,程式碼較為混亂,基本上實現遍歷的功能。
主要練習對結構體指標與連結串列的使用。*/  
typedef struct tree{  
       int key;  
       struct tree *left;  
       struct tree *right;  
   
}*BiTree,Node;  
BiTree *temp[100]={NULL};//存放當前根節點的指標
int flag=-1;//儲存當前棧頂位置
//迴圈建立二叉樹  
void CreateBiTree(BiTree &T)/*DEVC++無法編譯此句話,需要從vs中執行*/  
{    
     int word;  
     scanf("%d",&word);//輸入的節點值  
     if(word==-1)//-1表示該節點下面沒有左右孩子  
     {  
            T=NULL;  
     }  
     else  
     {    //生成當前的根節點 
			Node *p=(Node *) malloc (sizeof(Node));//開闢新的節點    
			T=p;
            T->key=word;  
            CreateBiTree(T->left);//遞迴建立左子樹  
            CreateBiTree(T->right); //遞迴建立右子樹   
     }  
}  
int isEmpty()//判斷棧是否為空 
{
	if(flag==-1)
		return 1;
	return 0;
}
void push(BiTree &T)//節點入棧
{
	flag++;
	BiTree *p=&T;
	temp[flag]=p;
}
BiTree *pop()//節點出棧
{
	BiTree t=*temp[flag];
	flag--;
	return &t;
}
void NonRecOrder(BiTree &T)//非遞迴前序遍歷
{
	BiTree t;//臨時節點
	push(T);//當前根節點入棧
	while(!isEmpty())//棧不為空則迴圈繼續
	{
		t=*pop();//取出當前棧頂節點
		printf("%d ",t->key);//獲取節點值
		if(t->left&&!(t->right))//當只有左孩子時,將左孩子入棧,並向下繼續搜尋
		{
			push(t->left);
			t=t->left;
		}
		else if(t->right&&!(t->left))//當只有右孩子時,將右孩子入棧,並繼續向下搜尋
		{
			push(t->right);
		 t=t->right;
		}
		else if(t->right&&t->left)//兩個孩子都有的情況先將右孩子入棧,再將左孩子入棧,並繼續向左孩子搜尋
		{
			push(t->right);
			push(t->left);
			t->left;
		}
	}
}
void PreOrder(BiTree &T)  //遞迴先序遍歷以T為根的二叉樹  
{  
     if(T)//T不為空或者根時   
     {  
            printf("%d ",T->key);//列印當前節點  
            PreOrder(T->left);  
            PreOrder(T->right);         
     }  
}  

int main(int argc, char *argv[])  
{  
  BiTree T;  
  printf("請依次輸入1,2,-1,3,4,-1,-1,-1,5,-1,6,-1,-1\n其中-1代表前面的節點沒有左孩子或者右孩子\n");  
  CreateBiTree(T);  
  printf("遞迴法先序遍歷的順序是\n");  
  PreOrder(T);  
  printf("\n非遞迴先序遍歷的順序是\n");  
  NonRecOrder(T);
  system("PAUSE");    
  return 0;  
}