樹的遍歷(包括遞歸和非遞歸)

記錄下來,以後找工作的時候複習複習.

#ifndef TREE_H
#define TREE_H
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
template <class typeName>struct node
{
	typeName key;
	node<typeName> *leftChild;
	node<typeName> *rightChild;
};
template <class typeName>class Tree
{
public:
	Tree(typeName key);
	void InsertNode(typeName key);//新增一個節點
	void PreTraver();//遞歸前序遍歷
	void PreTraverNonRec();//非遞歸前序遍歷
	void InTraver();//中序遍歷
	void InTraverNonRec();//非遞歸中序遍歷
	void PostTraver();//後續遍歷
	void PostTraverNonRec();//非遞歸後續遍歷
	void releaseNode();//釋放內存
	~Tree();
private:
	node<typeName> *CreateNode(typeName key);
	void InsertNode(typeName key,node<typeName> *pNode);
	void PreTraver(node<typeName > *pNode);
	void InTraver(node<typeName > *pNode);
	void PostTraver(node<typeName >*pNode);
private:
	node<typeName> root;
};

#endif

template<class typeName>
Tree<typeName>::Tree(typeName key)
{
	root.key=key;
	root.leftChild=NULL;
	root.rightChild=NULL;
}
template<class typeName>
node<typeName> *Tree<typeName>::CreateNode(typeName key)
{
	node<typeName> *pNode=new node<typeName>;
	if(NULL==pNode)
		return NULL;
	pNode->key=key;
	pNode->leftChild=NULL;
	pNode->rightChild=NULL;
	return pNode;
}
template<class typeName>
void Tree<typeName>::InsertNode(typeName key)
{
	InsertNode(key,&root);
}
template<class typeName>
void Tree<typeName>::InsertNode(typeName key, node<typeName> *pNode)
{
	if(pNode->key>key)
	{
		if(pNode->leftChild)
			InsertNode(key,pNode->leftChild);
		else
			pNode->leftChild=CreateNode(key);
	}else
		if(pNode->key<key)
		{
			if(pNode->rightChild)
				InsertNode(key,pNode->rightChild);
			else
				pNode->rightChild=CreateNode(key);
		}else
			if(pNode->key==key)
			{
				return ;
			}
}
template<class typeName>
void Tree<typeName>::PreTraver()
{
	PreTraver(&root);
}
template<class typeName>
void Tree<typeName>::PreTraver(node<typeName> *pNode)
{
	if(NULL!=pNode)
	{
		cout<<pNode->key<< " ";
		PreTraver(pNode->leftChild);
		PreTraver(pNode->rightChild);
	}
}
template<class typeName>
void Tree<typeName>::PreTraverNonRec()
{
	stack<node<typeName> *> pNodeStack;
	node<typeName> *pNode=&root;
	while(pNode||!pNodeStack.empty())
	{
		if(pNode)
		{
			cout<<pNode->key<<" ";
			pNodeStack.push(pNode);
			pNode=pNode->leftChild;
		}else
		{
			pNode=pNodeStack.top();
			pNodeStack.pop();
			pNode=pNode->rightChild;
		}
	}
	cout<<endl;
}
template<class typeName>
void Tree<typeName>::InTraver()
{
	InTraver(&root);
}
template<class typeName>
void Tree<typeName>::InTraver(node<typeName> *pNode)
{
	if(pNode)
	{
		InTraver(pNode->leftChild);
		cout<<pNode->key<<" ";
		InTraver(pNode->rightChild);
	}
}
template<class typeName>
void Tree<typeName>::InTraverNonRec()
{
	stack<node<typeName> *> pNodeStack;
	node<typeName >*pNode=&root;
	while(pNode || !pNodeStack.empty())
	{
		if(pNode)
		{
			pNodeStack.push(pNode);
			pNode=pNode->leftChild;
		}else
		{
			pNode=pNodeStack.top();
			cout<<pNode->key<<" ";
			pNodeStack.pop();
			pNode=pNode->rightChild;
		}
	}
	cout<<endl;
}
template<class typeName>
void Tree<typeName>::PostTraver()
{
	PostTraver(&root);
}
template<class typeName>
void Tree<typeName>::PostTraver(node<typeName> *pNode)
{
	if(pNode)
	{
		PostTraver(pNode->leftChild);
		PostTraver(pNode->rightChild);
		cout<<pNode->key<<" ";
	}
}
template<class typeName>
void Tree<typeName>::PostTraverNonRec()
{
	stack<node<typeName> *> pNodeStack;
	node<typeName> *pNode=&root;
	node<typeName> *preNode=NULL;
	while(pNode || !pNodeStack.empty())
	{
		if(pNode)
		{
			pNodeStack.push(pNode);
			pNode=pNode->leftChild;
		}else
		{
			pNode=pNodeStack.top();
			if(pNode->rightChild&&preNode!=pNode->rightChild)
			{
				pNode=pNode->rightChild;
			}else
			{
				cout<<pNode->key<<" ";
				preNode=pNode;
				pNodeStack.pop();
				pNode=NULL;
			}
		}
	}
	cout<<endl;
}
template<class typeName>
void Tree<typeName>::releaseNode()
{
	typeName rootKey=root.key;
	queue<node<typeName> *> pNodeQueue;
	node<typeName> *pFrontNode;
	pNodeQueue.push(&root);
	while(!pNodeQueue.empty())
	{
		pFrontNode=pNodeQueue.front();
		if(pFrontNode->leftChild)
		{
			pNodeQueue.push(pFrontNode->leftChild);
		}
		if(pFrontNode->rightChild)
			pNodeQueue.push(pFrontNode->rightChild);
		pNodeQueue.pop();
		if(pFrontNode->key!=rootKey)
			delete pFrontNode;
	}
}
template<class typeName>
Tree<typeName>::~Tree()
{
	releaseNode();
}


測試函數

//前三行代碼是爲了測試內存是否溢出.不過這種方式對類沒作用.
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include<iostream>
#include<string>
#include "tree.h"
using namespace std;
int main()
{
	Tree<string> iTree("j");
	iTree.InsertNode("a");
	iTree.InsertNode("q");
	iTree.InsertNode("o");
	iTree.InsertNode("c");
	iTree.InsertNode("g");
	iTree.InsertNode("k");
	iTree.InsertNode("r");
	cout<<"遞歸前序遍歷:";
	iTree.PreTraver();
	cout<<endl;
	cout<<"非遞歸前序遍歷:";
	iTree.PreTraverNonRec();
	cout<<"遞歸中序遍歷:";
	iTree.InTraver();
	cout<<endl;
	cout<<"非遞歸中序遍歷:";
	iTree.InTraverNonRec();
	cout<<"遞歸後序遍歷:";
	iTree.PostTraver();
	cout<<endl;
	cout<<"非遞歸後序遍歷:";
	iTree.PostTraverNonRec();
	_CrtDumpMemoryLeaks();//只能檢測這句話之前是否內存溢出,所以類裏面申請了內存,即使釋放了也會報內存溢出.
	return 0;
}


 

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