#ifndef BITREE_H #define BITREE_H #include #include using namespace std; #include "LinkedStack.h" #include "SeqQueue.h" #include "SeqStack.h" #include #include template struct BinTreeNode { T data; BinTreeNode *leftChild, *rightChild; BinTreeNode() : leftChild(NULL), rightChild(NULL) {} BinTreeNode(T x, BinTreeNode *l = NULL, BinTreeNode *r = NULL) : data(x), leftChild(l), rightChild(r) {} }; template class BinaryTree { public: BinaryTree() : root(NULL) {} BinaryTree(T value) : RefValue(value), root(new BinTreeNode(value)) {} BinaryTree(BinaryTree &s); ~BinaryTree() { destroy(); } bool IsEmpty() { return (root == NULL) ? true : false; } BinTreeNode *Parent(BinTreeNode *current) { return (root == NULL || root == current) ? NULL : Parent(root, current); } BinTreeNode *LeftChild(BinTreeNode *current) { return (current != NULL) ? current->leftChild : NULL; } BinTreeNode *RightChild(BinTreeNode *current) { return (current != NULL) ? current->rightChild : NULL; } void destroy() { destroy(root); } int Height() { return Height(root); } int Size() { return Size(root); } BinTreeNode *getRoot() const { return root; } void setRoot(BinTreeNode *p) { root = p; } void preOrder(void (*visit)(BinTreeNode *p)) { preOrder(root, visit); } void inOrder(void (*visit)(BinTreeNode *p)) { inOrder(root, visit); } void postOrder(void (*visit)(BinTreeNode *p)) { postOrder(root, visit); } void NonR_preOrder(void (*visit)(BinTreeNode *p)); //非递归前序遍历 void NonR_preOrder1(void (*visit)(BinTreeNode *p)); //非递归前序遍历 void NonR_inOrder(void (*visit)(BinTreeNode *p)); //非递归中序遍历 void NonR_postOrder(void (*visit)(BinTreeNode *p)); //非递归后续遍历 void levelOrder(void (*visit)(BinTreeNode *p)); BinTreeNode *Insert(BinTreeNode *curr, const T &x, int d); //作业:实现在curr结点左/右插入子女结点x BinTreeNode *Find(T item) const //作业:递归算法实现查找item { return Find(root, item); } int NonR_Height(); //作业:使用非递归方法求树高度 bool IsBalanced() //作业:递归算法判断二叉树是否为平衡二叉树 { int height; return IsBalanced(root, height); } protected: BinTreeNode *root; T RefValue; void CreateBinTree(istream &in, BinTreeNode *&subTree); void destroy(BinTreeNode *&subTree); BinTreeNode *Copy(BinTreeNode *orignode); int Height(BinTreeNode *subTree) const; int Size(BinTreeNode *subTree) const; BinTreeNode *Parent(BinTreeNode *subTree, BinTreeNode *current); BinTreeNode *Find(BinTreeNode *subTree, const T &x) const; //作业:使用递归方法实现查找 void Traverse(BinTreeNode *subTree, ostream &out); void preOrder(BinTreeNode *subTree, void (*visit)(BinTreeNode *p)); void inOrder(BinTreeNode *subTree, void (*visit)(BinTreeNode *p)); void postOrder(BinTreeNode *subTree, void (*visit)(BinTreeNode *p)); bool IsBalanced(BinTreeNode *subTree, int &height); friend istream &operator>>(istream &in, BinaryTree &Tree) { Tree.CreateBinTree(in, Tree.root); return in; }; friend ostream &operator<<(ostream &out, BinaryTree &Tree) { //输出二叉树 Tree.Traverse(Tree.root, out); out << endl; return out; }; friend int operator==(const BinaryTree &s, const BinaryTree &t) { return equal(s.root, t.root) ? true : false; }; //public: //void MakeTree(const T item,BinaryTree &left,BinaryTree& right); //void PrintBTree(BinTreeNode *BT,int level); }; template BinTreeNode *BinaryTree::Insert(BinTreeNode *curr, const T &x, int d) { /*在二叉树的curr结点左/右插入新子女结点x,原来的子女节点作为新结点的子女结点。d=0,左插入;d不等于0,右插入。插入成功返回新子女结点的地址。*/ //在这里添加你的程序替换下面的语句,完成任务1,实现在curr结点左/右插入子女结点x。 auto node = new BinTreeNode(x); node->leftChild = curr->leftChild; node->rightChild = curr->rightChild; if (d == 0) curr->leftChild = node, curr->rightChild = nullptr; else curr->leftChild = nullptr, curr->rightChild = node; return node; } template BinTreeNode *BinaryTree::Find(BinTreeNode *subtree, const T &x) const { //私有函数:在以subtree为根的二叉树中查找x,查找成功,返回结点地址,否则返回0。 //在这里添加你的程序替换下面的语句,完成任务2,实现在以subtree为根的二叉树中递归搜索结点x。 if (subtree == nullptr) return nullptr; if (x == subtree->data) return subtree; if (x < subtree->data) return Find(subtree->leftChild, x); if (x > subtree->data) return Find(subtree->rightChild, x); return NULL; } template void BinaryTree::destroy(BinTreeNode *&subTree) { // 私有函数,若指针subTree不为空,则删除根为subTree的子树 if (subTree != NULL) { destroy(subTree->leftChild); destroy(subTree->rightChild); delete subTree; subTree = NULL; } } template BinTreeNode *BinaryTree::Parent(BinTreeNode *subTree, BinTreeNode *current) { // 私有函数,从结点subTree开始,搜索结点current的父节点,若找到结点current的父节点,则函数返回父结点地址,否则返回NULL if (subTree == NULL) return NULL; if (subTree->leftChild == current || subTree->rightChild == current) return subTree; BinTreeNode *p = Parent(subTree->leftChild, current); if (p != NULL) return p; else return Parent(subTree->rightChild, current); } template void BinaryTree::Traverse(BinTreeNode *subTree, ostream &out) { if (subTree != NULL) { out << subTree->data << " "; Traverse(subTree->leftChild, out); Traverse(subTree->rightChild, out); } } template void BinaryTree::inOrder(BinTreeNode *subTree, void (*visit)(BinTreeNode *p)) { if (subTree != NULL) { inOrder(subTree->leftChild, visit); visit(subTree); inOrder(subTree->rightChild, visit); } } template void BinaryTree::preOrder(BinTreeNode *subTree, void (*visit)(BinTreeNode *p)) { if (subTree != NULL) { visit(subTree); preOrder(subTree->leftChild, visit); preOrder(subTree->rightChild, visit); } } template void BinaryTree::postOrder(BinTreeNode *subTree, void (*visit)(BinTreeNode *p)) { if (subTree != NULL) { postOrder(subTree->leftChild, visit); postOrder(subTree->rightChild, visit); visit(subTree); } } template int BinaryTree::Size(BinTreeNode *subTree) const { if (subTree == NULL) return 0; else return 1 + Size(subTree->leftChild) + Size(subTree->rightChild); } template int BinaryTree::Height(BinTreeNode *subTree) const { if (subTree == NULL) return 0; else { int i = Height(subTree->leftChild); int j = Height(subTree->rightChild); return (i < j) ? j + 1 : i + 1; } } template BinaryTree::BinaryTree(BinaryTree &s) { root = Copy(s.getRoot()); RefValue = s.RefValue; } template BinTreeNode *BinaryTree::Copy(BinTreeNode *orignode) { if (orignode == NULL) return NULL; BinTreeNode *temp = new BinTreeNode; temp->data = orignode->data; temp->leftChild = Copy(orignode->leftChild); temp->rightChild = Copy(orignode->rightChild); return temp; } template void BinaryTree::CreateBinTree(istream &in, BinTreeNode *&subTree) { T item; if (!in.eof()) { in >> item; if (item != RefValue) { subTree = new BinTreeNode(item); if (subTree == NULL) { cerr << "存储分配出错!" << endl; exit(1); } CreateBinTree(in, subTree->leftChild); CreateBinTree(in, subTree->rightChild); } else subTree = NULL; } } template int BinaryTree::NonR_Height() { //在这里添加你的程序替换下列语句,完成任务4,使用非递归方法求二叉树的高度。空树高度为0. queue *, int>> Q; int ans = 0; for (Q.push(make_pair(this->root, this->root != nullptr)); !Q.empty(); Q.pop()) { auto cur = Q.front(); ans = max(ans, cur.second); if (cur.first->leftChild) Q.push(make_pair(cur.first->leftChild, cur.second + 1)); if (cur.first->rightChild) Q.push(make_pair(cur.first->rightChild, cur.second + 1)); } return ans; } template bool BinaryTree::IsBalanced(BinTreeNode *subTree, int &height) { //如果每个结点的左子树和右子树的高度差的绝对值都小于2,则二叉树是平衡的。subTree二叉树如果是平衡的则返回true,否则返回false。 //subTree二叉树的高度通过形参height返回。 //在这里添加你的程序替换下面的语句,完成任务3,编写递归算法实现判断二叉树是否为平衡二叉树。 if (subTree == nullptr) return height = 0, true; int hl = 0, hr = 0; bool flag = true; if (flag) flag = flag && IsBalanced(subTree->leftChild, hl); if (flag) flag = flag && IsBalanced(subTree->rightChild, hr); if (flag) flag = flag && abs(hr - hl) < 2; return flag; } template void BinaryTree::NonR_preOrder(void (*visit)(BinTreeNode *p)) //非递归前序遍历 { SeqStack *> S; BinTreeNode *p; S.Push(root); while (!S.IsEmpty()) { S.Pop(p); visit(p); if (p->rightChild != NULL) S.Push(p->rightChild); if (p->leftChild != NULL) S.Push(p->leftChild); } } template void BinaryTree::NonR_preOrder1(void (*visit)(BinTreeNode *p)) //非递归前序遍历 { SeqStack *> S; BinTreeNode *p = root; S.Push(NULL); while (p != NULL) { visit(p); if (p->rightChild != NULL) S.Push(p->rightChild); if (p->leftChild != NULL) p = p->leftChild; else S.Pop(p); } } template void BinaryTree::NonR_inOrder(void (*visit)(BinTreeNode *p)) //非递归中序遍历 { SeqStack *> S; BinTreeNode *p = root; do { while (p != NULL) { S.Push(p); p = p->leftChild; } if (!S.IsEmpty()) { S.Pop(p); visit(p); p = p->rightChild; } } while (p != NULL || !S.IsEmpty()); } template struct stkNode { BinTreeNode *ptr; //树结点指针 enum { L, R } tag; //退栈标记,必须说明为枚举变量,tag移到最右边。这里最好用bool量 stkNode(BinTreeNode *N = NULL) { ptr = N; tag = L; } //构造函数 }; template void BinaryTree::NonR_postOrder(void (*visit)(BinTreeNode *p)) //非递归后序遍历 { LinkedStack> S; stkNode w; BinTreeNode *p = root; //p是遍历指针 do { while (p != NULL) { w.ptr = p; w.tag = stkNode::L; //枚举类型定义在struct stkNode中,如定义为全局性就简单了 S.Push(w); p = p->leftChild; } int continue1 = 1; //继续循环标记, 用于R while (continue1 && !S.IsEmpty()) { S.Pop(w); p = w.ptr; switch (w.tag) { //判断栈顶的tag标记 case stkNode::L: w.tag = stkNode::R; S.Push(w); continue1 = 0; p = p->rightChild; break; case stkNode::R: visit(p); break; } } } while (!S.IsEmpty()); //继续遍历其他结点 cout << endl; } template void BinaryTree::levelOrder(void (*visit)(BinTreeNode *p)) //非递归层序遍历 { SeqQueue *> Q; BinTreeNode *p = root; Q.EnQueue(p); while (!Q.IsEmpty()) { Q.DeQueue(p); visit(p); if (p->leftChild != NULL) Q.EnQueue(p->leftChild); if (p->rightChild != NULL) Q.EnQueue(p->rightChild); } } template bool equal(BinTreeNode *a, BinTreeNode *b) { if (a == NULL && b == NULL) return true; if (a != NULL && b != NULL && a->data == b->data && equal(a->leftChild, b->leftChild) && equal(a->rightChild, b->rightChild)) { //cout << a->data << endl;cout << b->data << endl; return true; } else { return false; } } template void PrintBTree(BinTreeNode *BT) { //以广义表形式输出二叉树 if (BT != NULL) { cout << BT->data; if (BT->leftChild != NULL || BT->rightChild != NULL) { cout << '('; PrintBTree(BT->leftChild); cout << ','; if (BT->rightChild != NULL) PrintBTree(BT->rightChild); cout << ')'; } else if (BT->leftChild == NULL && BT->rightChild == NULL) { cout << '('; cout << ','; cout << ')'; } } } template void PrintBTree(BinTreeNode *BT, int level) { //以凹入表形式输出二叉树 if (BT != NULL) //如果二叉树不空 { //二叉树root->Right()第level+1层结点数据域值的横向显示 PrintBTree(BT->rightChild, level + 1); if (level != 0) { //走过6*(level-1)个空格 for (int i = 0; i < 6 * (level - 1); i++) cout << " "; cout << "----"; //显示横线---- } cout << BT->data << endl; //显示结点的数据域值 //二叉树root->Left()第level+1层结点数据域值的横向显示 PrintBTree(BT->leftChild, level + 1); } } #endif