1. 程式人生 > >C++實現二叉樹之二叉連結串列

C++實現二叉樹之二叉連結串列

#include "stdafx.h"
#include <iostream>
#include <deque>

using namespace std;

template<typename T>
struct TreeNode{
	T data;                         //結點中的元素
	TreeNode<T> *Lchild, *Rchild;     //結點的左、右孩子結點指標
	//可選擇引數的預設建構函式
	//TreeNode<T>(T nodeValue, TreeNode<T> *rightNode = NULL, TreeNode<T> * leftNode = NULL) : data(nodeValue), Rchild(rightNode), Lchild(leftNode){}
};

template<typename T>
class BinaryTree{
public:
	//BinaryTree(){ }
	BinaryTree(){ root = CreatBT(root); }     //初始化一顆二叉樹,root指向根結點
	~BinaryTree(){ Destory(root); }
	TreeNode<T>* CreatBT(TreeNode<T> *rt);   //建立二叉樹
	TreeNode<T>* GetRoot(){ return root; };  //取指向二叉樹根結點的指標
	void PreOrder(TreeNode<T> *rt);          //前序遍歷
	void MidOrder(TreeNode<T> *rt);          //中序遍歷
	void PostOrder(TreeNode<T> *rt);         //後序遍歷
	void LevelOrder();                       //層序遍歷
	void Destory(TreeNode<T> *rt);           //銷燬二叉樹
	int Num_Node(TreeNode<T> *rt);          //統計二叉樹結點數
	int Depth(TreeNode<T> *rt);             //二叉樹深度
private:
	TreeNode<T> *root;            //指向根結點的頭指標,需要通過公共成員函式來呼叫
};

template<typename T>
TreeNode<T>* BinaryTree<T>::CreatBT(TreeNode<T> *rt){ //構造二叉樹,引數是一個指向結點的指標
	T nodeValue;
	cout << "輸入結點值:";
	cin >> nodeValue;
	if (nodeValue == -1)
		rt = NULL;
	else{
		rt = new TreeNode <T>;                       //建立一個樹結點
		rt->data = nodeValue;
		rt->Lchild = CreatBT(rt->Lchild);            //遞迴構造左子樹
		rt->Rchild = CreatBT(rt->Rchild);            //遞迴構造右子樹
	}
	return rt;
}

template<typename T>
void BinaryTree<T>::PreOrder(TreeNode<T> *rt){        //前序遍歷
	TreeNode<T> *p = rt;      
	if (p == NULL)
		return;
	else{
		cout << p->data << " ";                 //訪問根結點p的資料域
		PreOrder(p->Lchild);                    //前序遞迴遍歷p的左子樹
		PreOrder(p->Rchild);                    //前序遞迴遍歷p的右子樹
	}
}

template<typename T>
void BinaryTree<T>::MidOrder(TreeNode<T> *rt){
	TreeNode<T> *p = rt;
	if (p == NULL)
		return;
	else{
		MidOrder(p->Lchild);                   //中序遞迴遍歷p的左子樹
		cout << p->data << " ";                //訪問根結點p的資料域
		MidOrder(p->Rchild);                   //中序遞迴遍歷p的右子樹
	}
}

template<typename T>
void BinaryTree<T>::PostOrder(TreeNode<T> *rt){
	TreeNode<T> *p = rt;
	if (p == NULL)
		return;
	else{
		PostOrder(p->Lchild);                  //後序遞迴遍歷p的左子樹
		PostOrder(p->Rchild);                  //後序遞迴遍歷p的右子樹
		cout << p->data << " ";                //訪問根結點p的資料域
	}
}

template<typename T>
void BinaryTree<T>::LevelOrder(){              //層序遍歷,藉助一個deque容器
	if (root == NULL)
		return;
	deque<TreeNode<T>* > que;
	que.push_back(root);                       //隊尾入隊
	while (que.size()>0){
		TreeNode<T>* p = que.front();          //取隊首元素
		cout << p->data << " ";
		que.pop_front();                       //刪除隊首元素,返回void
		if (p->Lchild != NULL)                 //判讀該隊首元素是否存在左右孩子結點,
			que.push_back(p->Lchild);          
		if (p->Rchild != NULL)
			que.push_back(p->Rchild);
	}
}

template<typename T>
void BinaryTree<T>::Destory(TreeNode<T> *rt){    //銷燬二叉樹
	if (rt != NULL){
		Destory(rt->Lchild);                     //銷燬rt的左子樹
		Destory(rt->Rchild);                     //銷燬rt的右子樹
		delete rt;                               //銷燬rt結點
		cout << "已銷燬!" << endl;
	}
}

template<typename T>
int BinaryTree<T>::Num_Node(TreeNode<T> *rt){
	if (rt == NULL)
		return 0;
	else{
		return (1 + Num_Node(rt->Lchild) + Num_Node(rt->Rchild));
	}
}

template<typename T>
int BinaryTree<T>::Depth(TreeNode<T> *rt){
	if (rt == NULL)
		return 0;
	int h_left = Depth(rt->Lchild);
	int h_right = Depth(rt->Rchild);
	if (h_left > h_right)
		return (h_left + 1);
	else
		return (h_right + 1);
}


int _tmain(int argc, _TCHAR* argv[])
{
	BinaryTree<int> A;   //A初始化為空二叉樹
	TreeNode<int> *rootNode = A.GetRoot();    //取指向二叉樹根結點的指標
	cout << "前序遍歷:";
	A.PreOrder(rootNode);     
	cout << endl;
	cout << "中序遍歷:";
	A.MidOrder(rootNode);
	cout << endl;
	cout << "後序遍歷:";
	A.PostOrder(rootNode);
	cout << endl;
	cout << "層序遍歷:";
	A.LevelOrder();
	cout << endl;
	cout << "二叉樹結點個數:" << A.Num_Node(rootNode) << endl;
	cout << "二叉樹的深度:" << A.Depth(rootNode) << endl;
	return 0;
}