兩種方式遍歷二叉樹--遞歸方式和非遞歸方式

用遞歸的方法遍歷二叉樹很簡單,但是非遞歸的遍歷二叉樹就比較困難了。在非遞歸方法中,我們需要棧stack的幫助。以下是分別用遞歸方式和非遞歸方式寫的前、中、後序遍歷二叉樹的方法,經過驗證結果是正確的。

#include <iostream>
#include <stack>
using namespace std;
struct Node 
{
	int num;
	Node* pLeft;
	Node* pRight;
};
void insert(Node* &p,int num)
{
	Node* pTmp=new Node();
	pTmp->num=num;
	pTmp->pLeft=pTmp->pRight=NULL;

	if(p==NULL)
	{
		p=pTmp;
		return;
	}
	if(num<p->num)
		insert(p->pLeft,num);
	else if(num>p->num)
		insert(p->pRight,num);
	else
		return;

}
void PreOrder(Node* p)
{
	if(p==NULL)
		return;
	else
	{
		cout<<p->num<<" ";
		PreOrder(p->pLeft);
		PreOrder(p->pRight);
	}
}
void InOrder(Node* p)
{
	if (p==NULL)
		return;
	else
	{
		InOrder(p->pLeft);
		cout<<p->num<<" ";
		InOrder(p->pRight);
	}
}
void PostOrder(Node* p)
{
	if (p==NULL)
		return;
	else
	{
		PostOrder(p->pLeft);
		PostOrder(p->pRight);
		cout<<p->num<<" ";
	}
}
void PreOrderByLoop(Node* p)
{
	stack<Node*> MyStack;
	if(p==NULL)
		return;
	while(p!=NULL||!MyStack.empty())		//p和棧都爲空是結束循環的條件
	{
		while(p!=NULL)
		{
			MyStack.push(p);
			cout<<p->num<<" ";
			p=p->pLeft;
		}
		if(!MyStack.empty())		//從棧中取出一個節點的指針 
		{
			p=MyStack.top();
			MyStack.pop();
			p=p->pRight;			//當前節點的右孩子 當做一個子樹的根節點 從新開始循環
		}
	}
	cout<<endl;
}
void InOrderByLoop(Node* p)
{
	stack<Node*> Mystack;
	while(p!=NULL||!Mystack.empty())
	{
		while(p!=NULL)
		{
			Mystack.push(p);
			p=p->pLeft;
		}
		if(!Mystack.empty())
		{
			p=Mystack.top();
			Mystack.pop();
			cout<<p->num<<" ";
			p=p->pRight;
		}
	}
	cout<<endl;
}
void PostOrderByLoop(Node* p)
{
	stack<Node*> Mystack;
	Node* pre=NULL;						//剛剛訪問過的節點
	while(p!=NULL||!Mystack.empty())
	{
		while(p!=NULL)
		{
			Mystack.push(p);
			p=p->pLeft;
		}
		p=Mystack.top();
		if(p->pRight==NULL||p->pRight==pre)			//沒有右孩子 或者右孩子剛剛遍歷過了
		{
			cout<<p->num<<" ";
			Mystack.pop();
			pre=p;
			p=NULL;									//加這一句是爲了跳過入棧那部分程序
		}
		else
			p=p->pRight;
	}
	cout<<endl;
}
void main()
{
	Node* p=NULL;
	insert(p,10);
	insert(p,6);
	insert(p,14);
	insert(p,4);
	insert(p,8);
	insert(p,12);
	insert(p,16);
	insert(p,1);
	insert(p,5);
	insert(p,15);
	insert(p,17);
	insert(p,7);
	insert(p,9);

 	cout<<"Preorder:"<<endl;
 	PreOrder(p);
	cout<<endl<<"preorderbyLoop:"<<endl;
	PreOrderByLoop(p);

	cout<<endl<<"Inorder:"<<endl;
	InOrder(p);
	cout<<endl<<"InorderbyLoop:"<<endl;
	InOrderByLoop(p);

	cout<<endl<<"Postorder:"<<endl;
	PostOrder(p);
	cout<<endl<<"PostOrderByLoop:"<<endl;
	PostOrderByLoop(p);
}


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