【数据结构实验】链表储存的二叉树的模板类
数据结构实验要求写一个带四种迭代器(前序,中序,后序,层序)的二叉模板类,鄙人代码小白历经折磨后终于实现了,虽然可能还有点小瑕疵,但是大体上功能都能实现。
该模板还能实现二叉树左右子树的交换以及叶结点的计数;
代码如下:
头文件:
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;