【資料結構實驗】二叉樹的模板類
阿新 • • 發佈:2021-11-21
本文是給出一種二叉樹模板的實現以及四種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;