【c++模板实现】二叉查找树
捣鼓了一个晚上,最后还是照着书本把这BST弄出来了。悲催的娃娃啊,不动手写这个还真的很难啊!
BSTree.h
1 #ifndef BTREE_H_ 2 #define BTREE_H_ 3 4 #include <iostream> 5 using std::ostream; 6 7 template <class TreeDataType> 8 class BSTree 9 { 10 private: 11 class BSTNode 12 { 13 public: 14 BSTNode* left; 15 BSTNode* right; 16 TreeDataType data; BSTNode():left(NULL),right(NULL) {} 17 BSTNode(TreeDataType a_data):data(a_data),left(NULL),right(NULL) {} 18 };//节点声明 19 typedef BSTNode* BSTNodePointer; 20 BSTNodePointer m_root; 21 22 public: 23 BSTree():m_root(NULL) {} 24 ~BSTree() {deleteNode(m_root);} 25 bool isEmpty() const {return m_root == NULL;} 26 bool find(const TreeDataType& a_data) const; 27 void insert(const TreeDataType& a_data) {insertAux(m_root,a_data);} 28 void remove(const TreeDataType& a_data); 29 void inorder(ostream& out) const {inorderAux(out, m_root);} 30 void graph(ostream& out) const {graphAux(out, 0, m_root);} 31 32 protected: 33 void deleteNode(BSTNodePointer a_node);//删除节点和所有到子节点 34 void insertAux(BSTNodePointer& a_subRoot, const TreeDataType& a_data); 35 void inorderAux(ostream& out, BSTNodePointer a_subRoot) const; 36 void graphAux(ostream& out, int a_indent, BSTNodePointer a_subRoot) const; 37 void find2(const TreeDataType& a_data, bool& found, BSTNodePointer& a_locPtr, BSTNodePointer& a_parent) const; 38 };//类模板声明结束 39 #endif 40 41 template <class TreeDataType> 42 inline void BSTree<TreeDataType>::deleteNode(BSTree<TreeDataType>::BSTNodePointer a_node) 43 { 44 if (a_node->left != NULL) 45 { 46 deleteNode(a_node->left); 47 } 48 else if (a_node->right != NULL) 49 { 50 deleteNode(a_node->right); 51 } 52 else if (a_node != NULL) 53 { 54 delete a_node; 55 a_node = NULL; 56 } 57 } 58 59 template <class TreeDataType> 60 inline void BSTree<TreeDataType>::insertAux(BSTree<TreeDataType>::BSTNodePointer& a_subRoot, const TreeDataType& a_data) 61 { 62 if (a_subRoot == NULL) 63 { 64 a_subRoot = new BSTree<TreeDataType>::BSTNode(a_data); 65 } 66 else if (a_data < a_subRoot->data) 67 { 68 insertAux(a_subRoot->left,a_data); 69 } 70 else if (a_subRoot->data < a_data) 71 { 72 insertAux(a_subRoot->right,a_data); 73 } 74 else 75 { 76 std::cerr << "a_data already in the tree!\n"; 77 } 78 } 79 80 template <class TreeDataType> 81 inline void BSTree<TreeDataType>::inorderAux(ostream& out, BSTree<TreeDataType>::BSTNodePointer a_subRoot) const 82 { 83 if (a_subRoot != NULL) 84 { 85 inorderAux(out, a_subRoot->left);//L 86 out << a_subRoot->data << " ";//V 87 inorderAux(out, a_subRoot->right);//R 88 } 89 } 90 91 #include <iomanip> 92 using std::setw; 93 using std::endl; 94 template <class TreeDataType> 95 inline void BSTree<TreeDataType>::graphAux(ostream& out, int a_indent, BSTree<TreeDataType>::BSTNodePointer a_subRoot) const 96 { 97 if (a_subRoot != NULL) 98 { 99 graphAux(out, a_indent+8, a_subRoot->right); //R 100 out << setw(a_indent) << " " << a_subRoot->data << endl; //V 101 graphAux(out, a_indent+8, a_subRoot->left); //L 102 } 103 } 104 105 template <class TreeDataType> 106 inline bool BSTree<TreeDataType>::find(const TreeDataType& a_data) const 107 { 108 BSTree<TreeDataType>::BSTNodePointer locPtr = m_root; 109 bool found = false; 110 while (!found && locPtr != NULL) 111 { 112 if (a_data < locPtr->data) 113 { 114 locPtr = locPtr->left; 115 } 116 else if (locPtr->data < a_data) 117 { 118 locPtr = locPtr->right; 119 } 120 else 121 { 122 found = true; 123 } 124 } 125 return found; 126 } 127 128 template <class TreeDataType> 129 inline void BSTree<TreeDataType>::find2(const TreeDataType& a_data, bool& found, 130 BSTree<TreeDataType>::BSTNodePointer& a_locPtr, 131 BSTree<TreeDataType>::BSTNodePointer& a_parent) const 132 { 133 a_locPtr = m_root; 134 a_parent = NULL; 135 found = false; 136 while (!found && a_locPtr != NULL) 137 { 138 if (a_data < a_locPtr->data) 139 { 140 a_parent = a_locPtr; 141 a_locPtr = a_locPtr->left; 142 } 143 else if (a_locPtr->data < a_data) 144 { 145 a_parent = a_locPtr; 146 a_locPtr = a_locPtr->right; 147 } 148 else 149 { 150 found = true; 151 } 152 } 153 } 154 155 template <class TreeDataType> 156 inline void BSTree<TreeDataType>::remove(const TreeDataType& a_data) 157 { 158 bool found = false; 159 BSTree<TreeDataType>::BSTNodePointer x; //被删除的节点 160 BSTree<TreeDataType>::BSTNodePointer parent; 161 find2(a_data,found,x,parent); 162 if (!found) 163 { 164 std::cerr << "a_data is not in the tree!\n"; 165 return; 166 } 167 168 if (x->left != NULL && x->right != NULL)//节点有两个子女 169 { 170 //查找x的中续后继节点及其双亲节点 171 BSTree<TreeDataType>::BSTNodePointer xSucc = x->right; 172 parent = x; 173 while (xSucc->left != NULL) 174 { 175 parent = xSucc; 176 xSucc = xSucc->left; 177 } 178 x->data = xSucc->data; 179 x = xSucc; 180 } 181 BSTree<TreeDataType>::BSTNodePointer subTree = x->left; 182 if (subTree == NULL) 183 { 184 subTree = x->right; 185 } 186 if (parent == NULL) 187 { 188 m_root = subTree; 189 } 190 else if (parent->left == x) 191 { 192 parent->left = subTree; 193 } 194 else 195 { 196 parent->right = subTree; 197 } 198 delete x; 199 }
测试下结果
test.cpp
1 #include "BSTree.h" 2 #include <cstdlib> 3 #include <iostream> 4 using namespace std; 5 6 int main() 7 { 8 BSTree<int> intBST; 9 cout << "Constructing empty BST\n"; 10 cout << "BST " << (intBST.isEmpty()?"is":"is not") << "empty\n"; 11 12 int number; 13 for (;;) 14 { 15 cout << "Item to insert (-999 to stop):"; 16 cin >> number; 17 if (number == -999) break; 18 intBST.insert(number); 19 } 20 intBST.inorder(cout); 21 cout << endl; 22 intBST.graph(cout); 23 24 //测试find 25 for (;;) 26 { 27 cout << "Item to find (-999 to stop):"; 28 cin >> number; 29 if (number == -999) break; 30 bool found = intBST.find(number); 31 cout << boolalpha << found << endl; 32 } 33 34 //测试remove 35 for (;;) 36 { 37 cout << "Item to remove (-999 to stop):"; 38 cin >> number; 39 if (number == -999) break; 40 intBST.remove(number); 41 cout << endl; 42 intBST.graph(cout); 43 cout << endl; 44 } 45 intBST.inorder(cout); 46 return 0; 47 }
作者:涵曦(www.hanxi.cc)
出处:hanxi.cnblogs.com
GitHub:github.com/hanxi
Email:im.hanxi@gmail.com
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
《 Skynet 游戏服务器开发实战》
-
学习地址:
-
优惠推荐码:
2CZ2UA5u
-
可以先免费试学前 2 章内容