1. 程式人生 > >資料結構(四)之非遞迴遍歷二叉樹

資料結構(四)之非遞迴遍歷二叉樹

void Inoder(Bitree root)//二叉樹的中序遍歷非遞迴 
{
	IniStack(&S);//初始化一個棧
	p=root;
	while(!isEmpty(S)||p!=NULL)
	{
		if(p!=NULL)//如果當前結點不為空進棧 
		{
			push(S,p);
			p=p->left;//若該節點的左節點不為空,繼續進棧 
		}
		else//如果當前結點左節點為空出棧訪問該節點右子樹    或當前右節點為空出棧,此時為棧中保留的是該節點的前驅節點,繼續訪問右節點  
		{
			pop(S,p);//出棧 
			visit(p);//訪問該節點 
			p=p->right; //指向該節點右節點 
		}
	 } 
	
 }  
 void PostOrder(BiTree root)
 {
 	BiTNode *p,*q;
 	Stack S;
 	q=NULL;//q是訪問節點的右孩子 
 	p=root;
 	InitStack(&S);
 	while(p!=NULL||isEmpty(S))
 	{
 		if(p!=NULL)
 		{
 			p=p->left;
		 }
		 else
		 {
		 	Gettop(S,p);
			 if(p->right==NULL||p->right==q)
			 {
			 	visit(p);
			 	q=p;
			 	pop(S,p);
			 	p=NULL;
			  } 
			  else p=p->right;
		 	
		 	
		 }
	 }
 	
 }
 //表面上看遞迴演算法好像沒有呼叫棧,實際上遞迴演算法的執行需要反覆多次地呼叫自己,沒呼叫一次,系統內部都有系統執行棧區
 //在支援。需要保留本層引數,臨時變數與返回地址等,隨著函式遞迴呼叫,執行棧繼續增長,直到函式執行完才能徹底釋放佔用的空間。 
 

二叉樹中序非遞迴遍歷思路
p=root;
①如果棧不為空或者p不為空一直往左走 p=p->left
②如果p為空 出棧得到p節點,訪問p,p=p->right。重複以上步驟
二叉樹後序非遞迴思路
p=root;
①設計一個節點q用來儲存訪問的上一個節點
②如果棧不為空或者p不為空一直往左走p=p->left;
③如果p為空 取棧頂的值,如果棧頂值的右孩子等於NULL,或q,表明此節點的左右孩子都已訪問,把p賦值為NULL繼續退棧。如果棧頂的右孩子不等於NULL,或q,繼續訪問該節點的右孩子。重複以上步驟