二叉樹中序遍歷非遞歸算法實現詳解

二叉樹是數據結構中的經典結構,也是應用很廣泛的結構之一。二叉樹具有一些特定的性質,如 n0 = n2+1,在一些應用中,常常要求在樹中查找具有某些特徵的節點,或者對樹中節點進行處理,即遍歷二叉樹的問題,其遞歸算法非常容易實現,非遞歸算法也有兩種思路,本文將在程序中實現筆者認爲容易識記的一種方法。


輸入序列二叉樹:


程序實現:

#include <iostream>
#include <stack>


using std::cin;
using std::cout;
using std::endl;
using std::stack;


// 定義二叉樹結構, BiTree 爲指針類型
typedef struct BiTreeNode{
	int data;
	struct BiTreeNode *lchild,*rchild;
}BiTreeNode,*BiTree;


// &T 必須,可以試試去掉的後果 
// 輸入爲先序序列的順序,如圖 輸入序列爲: 1 2 0 0 3 4 6 0 0 7 0 0 5 0 8 0 0
// 0 - 表示 NULL,這裏爲了測試而設置的
BiTree fn_CreateBiTree(BiTree &T)
{
	int data;
	cin>>data;

	if(data==0)T=NULL; // 遇到值爲0的,將其置爲NULL,表示爲空
	else{
		if(!(T = (BiTree)new BiTreeNode))exit(0);
		T->data=data;
		fn_CreateBiTree(T->lchild);
		fn_CreateBiTree(T->rchild);
	}
	return(T);
}


// 先序遍歷 遞歸實現
void fn_PreOrderTraverse(BiTree T)
{
	if(T)
	{
		if(T->data)
		{
			cout<<T->data<<'\t';
			fn_PreOrderTraverse(T->lchild);
			fn_PreOrderTraverse(T->rchild);
		}
		return;
	}
	else 
		return;
}


// 中序遍歷 遞歸實現
void fn_MidOrderTraverse(BiTree T)
{
	if(T)
	{
		if(T->data)
		{
			fn_MidOrderTraverse(T->lchild);
			cout<<T->data<<'\t';
			fn_MidOrderTraverse(T->rchild);
		}
		return;	
	}
	else 
		return;
}


// 中序遍歷 非遞歸
void InOrderTraverse(BiTree T)
{
	stack<BiTree> NodeStack; // 需要用到棧
	BiTree p; // 遍歷的指針變量,類似於遊標功能

	if(T)	  // 非空二叉樹
	{
		p = T;
		while(p || !NodeStack.empty())	// 若p不爲空,或者棧非空,則進入循環
		{                               // 初始p非空,棧爲空
			if(p)
			{
				NodeStack.push(p);      // 將非空節點入棧,向左孩子遍歷
				p=p->lchild;
			}
			else                        // 此時p爲空,則p的父節點爲棧頂指針,爲分支最左的孩子,輸出
			{
				p = NodeStack.top();    // 將p賦值爲棧頂指針
				cout<<p->data<<'\t';          // 輸出分支最左孩子
				NodeStack.pop();        // 刪除棧頂指針
				p = p->rchild;          // 將p賦值給其右孩子,繼續遍歷其右孩子分支
			}
		}
	}
	else
		return;
}


void main(void)
{
	BiTree T;
	cout<<"輸入二叉樹序列,創建二叉樹:"<<endl;
	T = fn_CreateBiTree(T);
	cout<<endl;
	cout<<"輸出先序遍歷-遞歸算法:"<<endl;
	fn_PreOrderTraverse(T);
	cout<<endl;
	cout<<"輸出中序遍歷-遞歸算法:"<<endl;
	fn_MidOrderTraverse(T);
	cout<<endl;
	cout<<"輸出中序遍歷-非遞歸算法:"<<endl;
	InOrderTraverse(T);
	cout<<endl;
}


程序運行結果:


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