【二叉搜索树】
随机生成时平均深度为logN,平均插入、删除和搜索时间都是O(logN)。
可能存在的问题是数据不均衡,使树单边生长,极端情况下变成类似链表,最坏插入、删除、搜索时间O(N)
写这个例程也花了些时间,例程主要包括查找、插入、删除、遍历、清空几个内容。
同时避免之前写链表到了半途再修改,拷贝构造、拷贝赋值、析构也写成了深拷贝的模式。
光这两份代码在一起还无法运行,因为层序遍历那一块用了之前写的队列例程。
测试代码:

1 #include <iostream> 2 #include "bstree.h" 3 using bstree::BSTree; 4 int main(void) 5 { 6 //测试插入 7 BSTree<int> number; 8 cout << "additem" << endl; 9 number.additem(8);number.additem(4);number.additem(17);number.additem(3); 10 number.additem(6);number.additem(10);number.additem(18);number.additem(2); 11 number.additem(5);number.additem(7);number.additem(9);number.additem(15); 12 number.additem(19);number.additem(1);number.additem(14);number.additem(16); 13 number.additem(20); number.additem(13); number.additem(11); number.additem(12); 14 //打印 15 number.printpre(); 16 cout << "--preorder"<<endl; 17 number.printin(); 18 cout << "--inorder" << endl; 19 number.printpost(); 20 cout << "--postorder" << endl; 21 number.printseq(); 22 cout << "--seqorder" << endl; 23 24 //测试拷贝构造函数 25 cout << " copy constructor" << endl; 26 BSTree<int> number2(number); 27 number2.printpre(); 28 cout << "--preorder" << endl; 29 number2.printin(); 30 cout << "--inorder" << endl; 31 32 //测试插入重复元素 33 cout << " collision" << endl; 34 number.additem(1); 35 36 //删除测试 37 //删除节点没有右子树 38 cout << " remove number 3: iter->right = nullptr" << endl; 39 number.remove(3); 40 number.printpre(); 41 cout << "--preorder" << endl; 42 number.printin(); 43 cout << "--inorder" << endl; 44 45 //删除测试 46 //删除节点的右子树没有左子树 47 cout << " remove number 15: iter->right->left = nullptr" << endl; 48 number.remove(15); 49 number.printpre(); 50 cout << "--preorder" << endl; 51 number.printin(); 52 cout << "--inorder" << endl; 53 54 //删除测试 55 //删除节点的右子树有左子树 56 cout << " remove number 10: iter->right->left != nullptr" << endl; 57 number.remove(10); 58 number.printpre(); 59 cout << "--preorder" << endl; 60 number.printin(); 61 cout << "--inorder" << endl; 62 63 //删除测试 64 //删除根 65 cout << " remove number 8: iter == root" << endl; 66 number.remove(8); 67 number.printpre(); 68 cout << "--preorder" << endl; 69 number.printin(); 70 cout << "--inorder" << endl; 71 72 //删除测试 73 //删除不存在的元素 74 cout << " remove number not existed" << endl; 75 number.remove(21); 76 77 //查找最值 78 cout << " max = " << number.findmax()->data << endl; 79 cout << "min = " << number.findmin()->data << endl; 80 81 //清空树,并测试在空树下删除 82 cout << " clear" << endl; 83 number.clear(); 84 number.remove(3); 85 86 system("pause"); 87 }
实现代码:
1 #ifndef BINARYSEARCHTREE 2 #define BINARYSEARCHTREE 3 #include <iostream> 4 #include "queue.h" 5 using queue::Queue; 6 using std::cout; 7 using std::cin; 8 using std::endl; 9 using std::string; 10 using std::flush; 11 namespace bstree 12 { 13 template <typename T> struct Node 14 { 15 Node<T>() : left(nullptr), right(nullptr){} 16 Node<T>(const T &item) : data(item), left(nullptr), right(nullptr){} 17 T data; 18 Node<T>* left; 19 Node<T>* right; 20 }; 21 template <typename T> class BSTree 22 { 23 //构造函数 24 public: 25 BSTree() :nodes(0), root(nullptr){} 26 BSTree(const BSTree& another) 27 { 28 root = nullptr; 29 nodes = 0; 30 void(BSTree::*pf)(const Node<T>*); 31 pf = &BSTree::additem_from_another; 32 traverse_seq(another.root, pf); 33 } 34 ~BSTree(){ clear(); } 35 BSTree& operator=(const BSTree& another) 36 { 37 if (&another != this) 38 { 39 clear(); 40 void(BSTree::*pf)(const Node<T>*); 41 pf = &BSTree::additem_from_another; 42 traverse_seq(another.root, pf); 43 } 44 } 45 //接口 46 public: 47 //元素个数 48 unsigned int size()const{ return nodes; } 49 //是否空 50 bool empty()const{ return noodes == 0; } 51 //获得根指针 52 Node<T>* getroot()const{ return root; } 53 //各种遍历 54 //前中后序使用辅助函数递归完成,层序遍历需使用队列结构 55 void printpre()const{ traverse(root, printnode, 0); } 56 void printin()const{ traverse(root, printnode, 1); } 57 void printpost()const{ traverse(root, printnode, 2); } 58 void printseq()const{ traverse_seq(root, printnode); } 59 //#查找元素 60 Node<T>* find(const T &item)const; 61 //#查找最值 62 Node<T>* findmax()const; 63 Node<T>* findmin()const; 64 //#增加元素 65 bool additem(const T &item); 66 //#删除元素 67 bool remove(const T &item); 68 //清空树并将数据初始化 69 void clear(){ release(root); root = nullptr; nodes = 0; } 70 71 //辅助函数 72 private: 73 void release(Node<T>* iter); 74 Node<T>* find_prev(const T &item)const; 75 Node<T>* remove_node(Node<T>* iter); 76 void traverse(const Node<T>* iter, void(*fp)(const Node<T>*), int mode)const; 77 void traverse_seq(const Node<T>* iter, void(BSTree::*pf)(const Node<T>*)); 78 void traverse_seq(const Node<T>* iter, void(*pf)(const Node<T>*))const; 79 void additem_from_another(const Node<T>* iter){ additem(iter->data); } 80 //数据 81 private: 82 Node<T>* root; 83 unsigned int nodes; 84 }; 85 86 //辅助函数,打印节点元素 87 template <typename T> static void printnode(const Node<T>* iter){ cout << iter->data << " " << flush; } 88 //辅助函数 89 //查找元素的父树。如果树为空或元素为根,返回空指针;如果元素不存在,返回插入该元素时的父树 90 template <typename T> Node<T>* BSTree<T>::find_prev(const T &item)const 91 { 92 Node<T>* prev = nullptr; 93 Node<T>* curr = root; 94 while (curr != nullptr) 95 { 96 if (item < curr->data) 97 { 98 prev = curr; 99 curr = curr->left; 100 } 101 else if (item > curr->data) 102 { 103 prev = curr; 104 curr = curr->right; 105 } 106 else 107 break; 108 } 109 return prev; 110 } 111 //查找元素,如果元素不存在则返回空指针 112 template <typename T> Node<T>* BSTree<T>::find(const T &item)const 113 { 114 Node<T>* iter = find_prev(item); 115 if (iter == nullptr) 116 return root; 117 if (item < iter->data) 118 return iter->left; 119 else 120 return iter->right; 121 } 122 //查找最值 123 template <typename T> Node<T>* BSTree<T>::findmax()const 124 { 125 if (nodes == 0) 126 return nullptr; 127 Node<T>* iter = root; 128 while (iter->right != nullptr) 129 iter = iter->right; 130 return iter; 131 } 132 template <typename T> Node<T>* BSTree<T>::findmin()const 133 { 134 if (nodes == 0) 135 return nullptr; 136 Node<T>* iter = root; 137 while (iter->left != nullptr) 138 iter = iter->left; 139 return iter; 140 } 141 //插入元素,元素重复则报错 142 template <typename T> bool BSTree<T>::additem(const T &item) 143 { 144 Node<T>* prev = nullptr; 145 Node<T>* curr = root; 146 //找到待插入元素应该插入的位置 147 while (curr != nullptr) 148 { 149 if (item < curr->data) 150 { 151 prev = curr; 152 curr = curr->left; 153 } 154 else if (item > curr->data) 155 { 156 prev = curr; 157 curr = curr->right; 158 } 159 //元素相等导致冲突则报错 160 else 161 { 162 cout << "Elements collision!" << endl; 163 return false; 164 } 165 } 166 Node<T>* pnew = new Node<T>(item); 167 if (prev == nullptr) 168 root = pnew; 169 else if (item < prev->data) 170 prev->left = pnew; 171 else 172 prev->right = pnew; 173 ++nodes; 174 return true; 175 176 } 177 //删除元素 178 template <typename T> bool BSTree<T>::remove(const T &item) 179 { 180 if (nodes == 0) 181 { 182 cout << "Tree is empty!" << endl; 183 return false; 184 } 185 //函数主体执行查找操作 186 //查找到相应删除点后,交给remove_node()处理 187 Node<T>* iter = find_prev(item); 188 if (iter == nullptr) 189 { 190 if (root->data != item) 191 { 192 cout << "Not Found!" << endl; 193 return false; 194 } 195 root = remove_node(root); 196 } 197 else if (item < iter->data) 198 { 199 if (iter->left == nullptr) 200 { 201 cout << " Not Found!" << endl; 202 return false; 203 } 204 iter->left = remove_node(iter->left); 205 } 206 else 207 { 208 if (iter->right == nullptr) 209 { 210 cout << "Not Found!" << endl; 211 return false; 212 } 213 iter->right = remove_node(iter->right); 214 } 215 --nodes; 216 return true; 217 } 218 //辅助函数,删除具体节点 219 template <typename T> Node<T>* BSTree<T>::remove_node(Node<T>* iter) 220 { 221 //用即将被删除节点的右子树的最左边的子节点替代即将被删除的位置 222 //情况一,删除节点无右子树 223 if (iter->right == nullptr) 224 { 225 Node<T>* save = iter->left; 226 delete iter; 227 return save; 228 } 229 //情况二,删除节点的右子书无左子树 230 else if (iter->right->left == nullptr) 231 { 232 Node<T>* save = iter->right; 233 save->left = iter->left; 234 delete iter; 235 return save; 236 } 237 //情况三,删除节点的右子树有左子树 238 else 239 { 240 Node<T>* prev = iter->right; 241 Node<T>* curr = iter->right->left; 242 while (curr->left != nullptr) 243 { 244 prev = curr; 245 curr = curr->left; 246 } 247 prev->left = curr->right; 248 curr->left = iter->left; 249 curr->right = iter->right; 250 delete iter; 251 return curr; 252 } 253 } 254 //辅助函数,前中后遍历执行模式 255 template <typename T> void BSTree<T>::traverse(const Node<T>* iter, void(*fp)(const Node<T>*), int mode)const 256 { 257 if (iter == nullptr) 258 return; 259 if (mode == 0) 260 { 261 (*fp)(iter); 262 traverse(iter->left, fp, 0); 263 traverse(iter->right, fp, 0); 264 } 265 else if (mode == 1) 266 { 267 traverse(iter->left, fp, 1); 268 (*fp)(iter); 269 traverse(iter->right, fp, 1); 270 } 271 else if (mode == 2) 272 { 273 traverse(iter->left, fp, 2); 274 traverse(iter->right, fp, 2); 275 (*fp)(iter); 276 } 277 return; 278 } 279 //辅助函数,层序遍历,需队列辅助 280 //重载两个版本,一个用于遍历树不需改变树元素,调用非成员函数printnode。则标记const,函数参数为(*pf) 281 //另一个用于拷贝构造与拷贝赋值需改变树元素,调用成员函数。则不标记const,显示声明调用成员函数(BSTree::*pf) 282 template <typename T> void BSTree<T>::traverse_seq(const Node<T>* iter, void(BSTree::*pf)(const Node<T>*)) 283 { 284 if (iter != nullptr) 285 { 286 Queue<const decltype(iter)> node_address; 287 node_address.enqueue(iter); 288 while (!node_address.empty()) 289 { 290 const Node<T>* temp = node_address.getfirst(); 291 node_address.dequeue(); 292 if (temp->left != nullptr) 293 node_address.enqueue(temp->left); 294 if (temp->right != nullptr) 295 node_address.enqueue(temp->right); 296 (this->*pf)(temp); 297 } 298 } 299 } 300 template <typename T> void BSTree<T>::traverse_seq(const Node<T>* iter, void(*pf)(const Node<T>*))const 301 { 302 if (iter != nullptr) 303 { 304 Queue<const decltype(iter)> node_address; 305 node_address.enqueue(iter); 306 while (!node_address.empty()) 307 { 308 const Node<T>* temp = node_address.getfirst(); 309 node_address.dequeue(); 310 if (temp->left != nullptr) 311 node_address.enqueue(temp->left); 312 if (temp->right != nullptr) 313 node_address.enqueue(temp->right); 314 (*pf)(temp); 315 } 316 } 317 } 318 //辅助函数,释放所有节点清空内存 319 template <typename T> void BSTree<T>::release(Node<T>* iter) 320 { 321 if (iter == nullptr) 322 return; 323 release(iter->left); 324 release(iter->right); 325 delete(iter); 326 } 327 } 328 #endif