數據結構——18 二叉樹(非遞歸)

二叉樹——非遞歸法


二叉樹——使用非遞歸方法,創建樹、前中後序及層級遍歷樹。
建立樹時,按照左子樹小於樹根,右子樹大於樹根,這樣中序遍歷就是有序表

#include<iostream>
#include<queue>       //層級遍歷時,用到了queue模板類
#include<stack>       //前中後遍歷時,用到了stack模板類
using namespace std;
class node            //樹節點定義
{
public:
	int data;         //元素值
	node *parent;     //父節點
	node *left;       //左子節點
	node *right;      //右子節點
	int tag;        //這個在後序遍歷中用到,作爲標誌位
public:
//	node():data(-1),parent(NULL),left(NULL),right(NULL){};
	node(int num):data(num),parent(NULL),left(NULL),right(NULL),tag(0){};        //構造函數,初始化類成員變量

};

class tree            //樹定義
{
public:
	tree(int num[],int len);           //構造函數


	void insertNode(int data);         //安左低右高插入樹的節點
	void preOrderTree();               //前序
	void inOrderTree();                //中序             
	void postOrderTree();              //後序
	void levelOrderTree();             //層級遍歷


private:
	node *root;                        //樹的根節點
};

tree::tree(int num[],int len)          //構造函數,插入樹節點
{
	root=new node(num[0]);
	for(int i=1;i<len;i++)
		insertNode(num[i]);
}
void tree::insertNode(int data)
{
	node *p,*par;
	node *newnode=new node(data);
	p=par=root;


	while(p)
	{
		par=p;
		if(data > p->data)
			p=p->right;
		else if(data < p->data)
			p=p->left;
		else if(data == p->data)
		{
			delete newnode;
			return;
		}
	}


	newnode->parent=par;
	if(par->data > newnode->data)
		par->left=newnode;
	else
		par->right=newnode;
}

void tree::preOrderTree()             //先序遍歷
{
	stack<node *> s;
	node *p=root;                     //從根節點開始
	
	while(p|| !s.empty())             //樹不爲空或棧不爲空
	{
		while(p)                      //遍歷左子樹,壓入棧,入棧前,輸出節點
		{
			cout<<p->data<<"  ";
			s.push(p);
			p=p->left;
			
		}
		if(!s.empty())
		{
			p=s.top();
			s.pop();
			p=p->right;
		}
	}
}

void tree::inOrderTree()            //中序遍歷
{
	stack<node *> s;
	node *p=root;                   //從根節點開始
	 
	while(p|| !s.empty())           //樹不爲空或棧不爲空
	{
		while(p)                    //遍歷左子樹,壓入棧
		{
			s.push(p);
			p=p->left;
		}
		if(!s.empty())
		{
			p=s.top();              //p指向棧頂
			s.pop();                //出棧
			cout<<p->data<<"  ";
			p=p->right;             //指向這個節點的右子樹,遍歷右子樹做準備
		}
	}
}

void tree::postOrderTree()           //後序遍歷
{
	stack<node *> s;
	node *p=root;
	
	while(p|| !s.empty())
	{
		while(p)
		{
			s.push(p);
			p=p->left;
			
		}
		if(!s.empty())
		{
			p=s.top();
			if(p->tag)       //tag爲0表示遍歷左子樹前的保護現場,tag爲1表示遍歷右子樹前的現場保護
			{
			cout<<p->data<<"  ";
			s.pop();
			p=NULL;
			}
			else
			{
				p->tag=1;
				p=p->right;
			
			}
			
		}
	}
}

void tree::levelOrderTree()    //層級遍歷
{
	queue<node *> q;           //定義一個隊列
	node *ptr=NULL;


	q.push(root);
	while(!q.empty())
	{
		ptr=q.front();         //得到隊列的頭節點
		q.pop();               //出隊列
		cout<<ptr->data<<"  ";


		if(ptr->left!=NULL)    //當前節點存在左節點,左節點入隊
			q.push(ptr->left);
		if(ptr->right!=NULL)   //當前節點存在右節點,右節點入隊
			q.push(ptr->right);	
	}
}


int main()
{
	int num[8]={5,3,7,2,4,6,8,1};
	tree t(num,8);


	cout<<"前序遍歷:  ";
	t.preOrderTree();
	cout<<endl<<endl;


	cout<<"中序遍歷:  ";
	t.inOrderTree();
	cout<<endl<<endl;


	cout<<"後序遍歷:  ";
	t.postOrderTree();
	cout<<endl<<endl;


	cout<<"層級遍歷:  ";
	t.levelOrderTree();
	cout<<endl;
	return 0;
}


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