1. 程式人生 > 其它 >【資料結構實驗】二叉樹的模板類

【資料結構實驗】二叉樹的模板類

本文是給出一種二叉樹模板的實現以及四種forward迭代器

資料結構實驗要求寫一個帶四種迭代器(前序,中序,後序,層序)的二叉模板類,鄙人程式碼小白歷經折磨後終於實現了,雖然可能還有點小瑕疵,但是大體上功能都能實現。

該模板還能實現二叉樹左右子樹的交換以及葉結點的計數;

程式碼如下:

標頭檔案:

template<typename T>
struct BinTreeNode {
	T data;
	BinTreeNode<T>* leftChild, * rightChild;
	bool visited;
	BinTreeNode();
	BinTreeNode(T x, BinTreeNode<T>* l=NULL , BinTreeNode<T>* r=NULL,bool v=false);
};

template<typename T>
class MyBinaryTree {
public:
	MyBinaryTree(T value);
	MyBinaryTree(MyBinaryTree<T>& BT); 
	MyBinaryTree(MyBinaryTree<T>& b1, T& item, MyBinaryTree<T>& b2);  //Creat a binary tree whose left subtree is b1,right subtree is b2,and whose root contains item.
	~MyBinaryTree();
	BinTreeNode<T>* GetRoot()const;
	void Linkroot(BinTreeNode<T>*& MBT);
	MyBinaryTree<T> LeftSubtree(); //return the leftsubtree of *this;
	MyBinaryTree<T> RightSubtree(); // return the rightsubtree of *this;
	T RootData(); //return the data in the root node.
	bool IsEmpty();
	void preOrder(); //前序遍歷
	void inOrder(); //中序遍歷
	void postOrder(); //後序遍歷
	void levelOrder(); //層序遍歷
	void CreatBinTree(BinTreeNode<T>*& subTree); //前序建立二叉樹
	int LeavesNum(BinTreeNode<T>* MBT); //計算葉結點數目的函式
	void Swap(BinTreeNode<T>* MBT);  //交換左右子樹(映象)
	void PrePrint(); //前序輸出
	void InPrint();  //中序輸出
	void PostPrint();  //後序輸出
	void LevelPrint(); //層序輸出
public:
	class PreorderIterator {
	public:
		PreorderIterator(BinTreeNode<T>*);
		T* Next();
		std::stack<BinTreeNode<T>*> S;
		BinTreeNode<T>* currentNode;
	};
	class InorderIterator {
	public:
		InorderIterator(BinTreeNode<T>*);
		T* Next(); 
		std::stack<BinTreeNode<T>*> S;
		BinTreeNode<T>* currentNode;
	};
	class PostorderIterator {
	public:
		PostorderIterator(BinTreeNode<T>*);
		T* Next();
		std::stack<BinTreeNode<T>*> S;
		BinTreeNode<T>* currentNode;
	};
	class LevelorderIterator {
	public:
		LevelorderIterator(BinTreeNode<T>* BST);
		T* Next();
		std::queue<BinTreeNode<T>*> Q;
		BinTreeNode<T>* currentNode;
	};
private:
	BinTreeNode<T>* root; 
	T RefValue; //建樹時資料輸入停止的標誌;
	void Destory(BinTreeNode<T>*& subtree);
	void preOrder(BinTreeNode<T>* MST);
	void inOrder(BinTreeNode<T>* MST);
	void postOrder(BinTreeNode<T>* MST);
	BinTreeNode<T>* Copy(BinTreeNode<T>* MST);
};

#endif

樹的方法實現及迭代器的初始化:

template<typename T>
BinTreeNode<T>::BinTreeNode() {
	leftChild = nullptr;
	rightChild = nullptr;
	data = 0;
}

template<typename T>
BinTreeNode<T>::BinTreeNode(T x, BinTreeNode<T>* l , BinTreeNode<T>* r,bool v ) :data(x), leftChild(l), rightChild(r),visited(v){ }

template<typename T>
MyBinaryTree<T>::MyBinaryTree(T value) {
	root = nullptr;
	RefValue = value;
}

template<typename T>
MyBinaryTree<T>::MyBinaryTree(MyBinaryTree<T>& BT) {
	root = Copy(BT.root);
}

template<typename T>
MyBinaryTree<T>::MyBinaryTree(MyBinaryTree<T>& b1, T& item, MyBinaryTree<T>& b2) {
	root->leftChild = b1.root;
	root->rightChild = b2.root;
	root->data = item;
}

template<typename T>
MyBinaryTree<T>::~MyBinaryTree() {
	Destory(root);
}

template<typename T>
BinTreeNode<T>* MyBinaryTree<T>::GetRoot()const {
	return root;
}

template<typename T>
void MyBinaryTree<T>::Linkroot(BinTreeNode<T>* &MBT) {
	root = MBT;
}

template<typename T>
MyBinaryTree<T> MyBinaryTree<T>::LeftSubtree() {
	return (root->leftChild != NULL) ? root->leftChild : NULL;
}

template<typename T>
MyBinaryTree<T> MyBinaryTree<T>::RightSubtree() {
	return (root->rightChild != NULL) ? root->rightChild : NULL;
}

template<typename T>
T MyBinaryTree<T>::RootData() {
	return root->data;
}

template<typename T>
bool MyBinaryTree<T>::IsEmpty() {
	return (root == NULL) ? true:false;
}

template<typename T>
void MyBinaryTree<T>::Destory(BinTreeNode<T>*& subtree) {
	if (subtree != NULL) {
		Destory(subtree->leftChild);
		Destory(subtree->rightChild);
		delete subtree;
	}
}

template<typename T>
void MyBinaryTree<T>::preOrder() {
	preOrder(root);
}

template<typename T>
void MyBinaryTree<T>::inOrder() {
	inOrder(root);
}

template<typename T>
void MyBinaryTree<T>::postOrder() {
	postOrder(root);
}

template<typename T>
void MyBinaryTree<T>::preOrder(BinTreeNode<T>* MST) {
	if (MST) {
		std::cout << MST->data;
		preOrder(MST->leftChild);
		preOrder(MST->rightChild);
	}
}

template<typename T>
void MyBinaryTree<T>::inOrder(BinTreeNode<T>* MST) {
	if (MST) {
		inOrder(MST->leftChild);
		std::cout << MST->data;
		inOrder(MST->rightChild);
	}
}

template<typename T>
void MyBinaryTree<T>::postOrder(BinTreeNode<T>* MST) {
	if (MST) {
		postOrder(MST->leftChild);
		postOrder(MST->rightChild);
		std::cout << MST->data;
	}
}

template<typename T>
void MyBinaryTree<T>::levelOrder() {
	std::queue<BinTreeNode<T>*>Q;
	BinTreeNode<T>* p = root;
	Q.push(p);
	while (!Q.empty()) {
		p = Q.front();
		Q.pop();
		std::cout << p->data;
		if(p->leftChild!=NULL)
			Q.push(p->leftChild);
		if(p->rightChild!=NULL)
			Q.push(p->rightChild);
	}
}
template<typename T>
BinTreeNode<T>* MyBinaryTree<T>::Copy(BinTreeNode<T>* BS) {
	if (!BS)
		return NULL;
	else
		return new BinTreeNode<T>(BS->data, Copy(BS->leftChild), Copy(BS->rightChild));

}
template<typename T>
void MyBinaryTree<T>::CreatBinTree(BinTreeNode<T>*& subtree){
	T item;
	std::cin>> item;
	if (item != RefValue) {
		subtree = new BinTreeNode<T>(item);
		if (subtree == NULL) {
			std::cerr << "Wrong!" << std::endl;
			exit(1);
		}
		CreatBinTree(subtree->leftChild);
		CreatBinTree(subtree->rightChild);
	}
	else subtree = NULL;
}

template<typename T>
void MyBinaryTree<T>::PrePrint() {
	T* i;
	std::cout << "前序輸出:";
	MyBinaryTree<T>::PreorderIterator PRE= PreorderIterator(root);
	while (1) {
		i = PRE.Next();
		if(i)
		std::cout << *i << " ";
		if (!i)
			break;
	}
}

template<typename T>
void MyBinaryTree<T>::InPrint() {
	T* i;
	std::cout << "中序輸出:";
	MyBinaryTree<T>::InorderIterator IN= InorderIterator(root);
	while (1) {
		i = IN.Next();
		if (i)
			std::cout << *i << " ";
		if (!i)
			break;
	}
}

template<typename T>
void MyBinaryTree<T>::PostPrint() {
	T* i;
	std::cout << "後序輸出:";
	MyBinaryTree<T>::PostorderIterator Pos= PostorderIterator(root);
	while (1) {
		i = Pos.Next();
		if (i)
			std::cout << *i << " ";
		if (!i)
			break;
	}
}

template<typename T>
void MyBinaryTree<T>::LevelPrint() {
	T* i;
	std::cout << "層序輸出:";
	MyBinaryTree<T>::LevelorderIterator LOI= LevelorderIterator(root);
	while (1) {
		i = LOI.Next();
		if (i)
			std::cout << *i << " ";
		if (!i)
			break;
	}
}

template<typename T>
int MyBinaryTree<T>::LeavesNum(BinTreeNode<T>* MBT) {
	if (!MBT)
		return 0;
	else if (MBT->leftChild == NULL && MBT->rightChild==NULL)
		return 1;
	else
		return LeavesNum(MBT->leftChild) + LeavesNum(MBT->rightChild);
}

template<typename T>
void MyBinaryTree<T>::Swap(BinTreeNode<T>* MBT) {
	if (!MBT)
		return;
	BinTreeNode<T>* Temp;
	Temp=MBT->rightChild;
	MBT->rightChild = MBT->leftChild;
	MBT->leftChild = Temp;
	Swap(MBT->leftChild);
	Swap(MBT->rightChild);
}

template<typename T>
MyBinaryTree<T>::PreorderIterator::PreorderIterator(BinTreeNode<T>* BST) {
	currentNode = BST; 
}

template<typename T>
MyBinaryTree<T>::InorderIterator::InorderIterator(BinTreeNode<T>* BST) {
	currentNode = BST;
}

template<typename T>
MyBinaryTree<T>::PostorderIterator::PostorderIterator(BinTreeNode<T>* BST) {
	currentNode = BST;
}

template<typename T>
MyBinaryTree<T>::LevelorderIterator::LevelorderIterator(BinTreeNode<T>* BST) {
	currentNode = BST;
}

迭代器的實現:

template<typename T>
T* MyBinaryTree<T>::PreorderIterator::Next() {
	T& temp = currentNode->data;
	if (currentNode) {
		if (currentNode->rightChild)
			S.push(currentNode->rightChild);
		if (currentNode->leftChild)
			S.push(currentNode->leftChild);

	}
	if (!currentNode)
		return NULL;
	if (!S.empty()) {
		currentNode = S.top();
		S.pop();
	}
	else {
		currentNode = NULL;
	}
	return &temp;
}

template<typename T>
T* MyBinaryTree<T>::InorderIterator::Next() {
	while (currentNode) {
		S.push(currentNode);
		currentNode = currentNode->leftChild;
	}
	if (S.empty())
		return 0;
	currentNode = S.top();
	S.pop();
	T& temp = currentNode->data;
	currentNode = currentNode->rightChild;
	return &temp;
}

template<typename T>
T* MyBinaryTree<T>::PostorderIterator::Next() {
	while (currentNode) {
		if (!currentNode->visited) {
			S.push(currentNode);
			currentNode->visited = true;
		}
		if (currentNode->rightChild && !currentNode->rightChild->visited) {
			S.push(currentNode->rightChild);
			currentNode->rightChild->visited = true;
		}
		if (currentNode->leftChild && !currentNode->leftChild->visited) {
			currentNode = currentNode->leftChild;
			continue;
		}
		currentNode = currentNode->rightChild;
	}
	if (S.empty())
		return 0;
	currentNode = S.top();
	S.pop();
	T& temp = currentNode->data;
	return &temp;
}


template<typename T>
T* MyBinaryTree<T>::LevelorderIterator::Next() {
	T& temp = currentNode->data;
	if (currentNode) {
		if (currentNode->leftChild) 
			Q.push(currentNode->leftChild);
		if (currentNode->rightChild)
			Q.push(currentNode->rightChild);
	}
	if (!currentNode)
		return 0;
	if (!Q.empty()) {
		currentNode = Q.front();
		Q.pop();
	}
	else
		currentNode = NULL;
	return &temp;