C++ 二叉树知识点
作者:互联网
1 /** 2 * C++ 语言: 二叉查找树 3 * 4 * @author skywang 5 * @date 2013/11/07 6 */ 7 8 #ifndef _BINARY_SEARCH_TREE_HPP_ 9 #define _BINARY_SEARCH_TREE_HPP_ 10 11 #include <iomanip> 12 #include <iostream> 13 using namespace std; 14 15 template <class T> 16 class BSTNode{ 17 public: 18 T key; // 关键字(键值) 19 BSTNode *left; // 左孩子 20 BSTNode *right; // 右孩子 21 BSTNode *parent;// 父结点 22 23 BSTNode(T value, BSTNode *p, BSTNode *l, BSTNode *r): 24 key(value),parent(),left(l),right(r) {} 25 }; 26 27 template <class T> 28 class BSTree { 29 private: 30 BSTNode<T> *mRoot; // 根结点 31 32 public: 33 BSTree(); 34 ~BSTree(); 35 36 // 前序遍历"二叉树" 37 void preOrder(); 38 // 中序遍历"二叉树" 39 void inOrder(); 40 // 后序遍历"二叉树" 41 void postOrder(); 42 43 // (递归实现)查找"二叉树"中键值为key的节点 44 BSTNode<T>* search(T key); 45 // (非递归实现)查找"二叉树"中键值为key的节点 46 BSTNode<T>* iterativeSearch(T key); 47 48 // 查找最小结点:返回最小结点的键值。 49 T minimum(); 50 // 查找最大结点:返回最大结点的键值。 51 T maximum(); 52 53 // 找结点(x)的后继结点。即,查找"二叉树中数据值大于该结点"的"最小结点"。 54 BSTNode<T>* successor(BSTNode<T> *x); 55 // 找结点(x)的前驱结点。即,查找"二叉树中数据值小于该结点"的"最大结点"。 56 BSTNode<T>* predecessor(BSTNode<T> *x); 57 58 // 将结点(key为节点键值)插入到二叉树中 59 void insert(T key); 60 61 // 删除结点(key为节点键值) 62 void remove(T key); 63 64 // 销毁二叉树 65 void destroy(); 66 67 // 打印二叉树 68 void print(); 69 private: 70 // 前序遍历"二叉树" 71 void preOrder(BSTNode<T>* tree) const; 72 // 中序遍历"二叉树" 73 void inOrder(BSTNode<T>* tree) const; 74 // 后序遍历"二叉树" 75 void postOrder(BSTNode<T>* tree) const; 76 77 // (递归实现)查找"二叉树x"中键值为key的节点 78 BSTNode<T>* search(BSTNode<T>* x, T key) const; 79 // (非递归实现)查找"二叉树x"中键值为key的节点 80 BSTNode<T>* iterativeSearch(BSTNode<T>* x, T key) const; 81 82 // 查找最小结点:返回tree为根结点的二叉树的最小结点。 83 BSTNode<T>* minimum(BSTNode<T>* tree); 84 // 查找最大结点:返回tree为根结点的二叉树的最大结点。 85 BSTNode<T>* maximum(BSTNode<T>* tree); 86 87 // 将结点(z)插入到二叉树(tree)中 88 void insert(BSTNode<T>* &tree, BSTNode<T>* z); 89 90 // 删除二叉树(tree)中的结点(z),并返回被删除的结点 91 BSTNode<T>* remove(BSTNode<T>* &tree, BSTNode<T> *z); 92 93 // 销毁二叉树 94 void destroy(BSTNode<T>* &tree); 95 96 // 打印二叉树 97 void print(BSTNode<T>* tree, T key, int direction); 98 }; 99 100 /* 101 * 构造函数 102 */ 103 template <class T> 104 BSTree<T>::BSTree():mRoot(NULL) 105 { 106 } 107 108 /* 109 * 析构函数 110 */ 111 template <class T> 112 BSTree<T>::~BSTree() 113 { 114 destroy(); 115 } 116 117 /* 118 * 前序遍历"二叉树" 119 */ 120 template <class T> 121 void BSTree<T>::preOrder(BSTNode<T>* tree) const 122 { 123 if(tree != NULL) 124 { 125 cout<< tree->key << " " ; 126 preOrder(tree->left); 127 preOrder(tree->right); 128 } 129 } 130 131 template <class T> 132 void BSTree<T>::preOrder() 133 { 134 preOrder(mRoot); 135 } 136 137 /* 138 * 中序遍历"二叉树" 139 */ 140 template <class T> 141 void BSTree<T>::inOrder(BSTNode<T>* tree) const 142 { 143 if(tree != NULL) 144 { 145 inOrder(tree->left); 146 cout<< tree->key << " " ; 147 inOrder(tree->right); 148 } 149 } 150 151 template <class T> 152 void BSTree<T>::inOrder() 153 { 154 inOrder(mRoot); 155 } 156 157 /* 158 * 后序遍历"二叉树" 159 */ 160 template <class T> 161 void BSTree<T>::postOrder(BSTNode<T>* tree) const 162 { 163 if(tree != NULL) 164 { 165 postOrder(tree->left); 166 postOrder(tree->right); 167 cout<< tree->key << " " ; 168 } 169 } 170 171 template <class T> 172 void BSTree<T>::postOrder() 173 { 174 postOrder(mRoot); 175 } 176 177 /* 178 * (递归实现)查找"二叉树x"中键值为key的节点 179 */ 180 template <class T> 181 BSTNode<T>* BSTree<T>::search(BSTNode<T>* x, T key) const 182 { 183 if (x==NULL || x->key==key) 184 return x; 185 186 if (key < x->key) 187 return search(x->left, key); 188 else 189 return search(x->right, key); 190 } 191 192 template <class T> 193 BSTNode<T>* BSTree<T>::search(T key) 194 { 195 search(mRoot, key); 196 } 197 198 /* 199 * (非递归实现)查找"二叉树x"中键值为key的节点 200 */ 201 template <class T> 202 BSTNode<T>* BSTree<T>::iterativeSearch(BSTNode<T>* x, T key) const 203 { 204 while ((x!=NULL) && (x->key!=key)) 205 { 206 if (key < x->key) 207 x = x->left; 208 else 209 x = x->right; 210 } 211 212 return x; 213 } 214 215 template <class T> 216 BSTNode<T>* BSTree<T>::iterativeSearch(T key) 217 { 218 iterativeSearch(mRoot, key); 219 } 220 221 /* 222 * 查找最小结点:返回tree为根结点的二叉树的最小结点。 223 */ 224 template <class T> 225 BSTNode<T>* BSTree<T>::minimum(BSTNode<T>* tree) 226 { 227 if (tree == NULL) 228 return NULL; 229 230 while(tree->left != NULL) 231 tree = tree->left; 232 return tree; 233 } 234 235 template <class T> 236 T BSTree<T>::minimum() 237 { 238 BSTNode<T> *p = minimum(mRoot); 239 if (p != NULL) 240 return p->key; 241 242 return (T)NULL; 243 } 244 245 /* 246 * 查找最大结点:返回tree为根结点的二叉树的最大结点。 247 */ 248 template <class T> 249 BSTNode<T>* BSTree<T>::maximum(BSTNode<T>* tree) 250 { 251 if (tree == NULL) 252 return NULL; 253 254 while(tree->right != NULL) 255 tree = tree->right; 256 return tree; 257 } 258 259 template <class T> 260 T BSTree<T>::maximum() 261 { 262 BSTNode<T> *p = maximum(mRoot); 263 if (p != NULL) 264 return p->key; 265 266 return (T)NULL; 267 } 268 269 /* 270 * 找结点(x)的后继结点。即,查找"二叉树中数据值大于该结点"的"最小结点"。 271 */ 272 template <class T> 273 BSTNode<T>* BSTree<T>::successor(BSTNode<T> *x) 274 { 275 // 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。 276 if (x->right != NULL) 277 return minimum(x->right); 278 279 // 如果x没有右孩子。则x有以下两种可能: 280 // (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。 281 // (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结点"。 282 BSTNode<T>* y = x->parent; 283 while ((y!=NULL) && (x==y->right)) 284 { 285 x = y; 286 y = y->parent; 287 } 288 289 return y; 290 } 291 292 /* 293 * 找结点(x)的前驱结点。即,查找"二叉树中数据值小于该结点"的"最大结点"。 294 */ 295 template <class T> 296 BSTNode<T>* BSTree<T>::predecessor(BSTNode<T> *x) 297 { 298 // 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。 299 if (x->left != NULL) 300 return maximum(x->left); 301 302 // 如果x没有左孩子。则x有以下两种可能: 303 // (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。 304 // (01) x是"一个左孩子",则查找"x的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"x的前驱结点"。 305 BSTNode<T>* y = x->parent; 306 while ((y!=NULL) && (x==y->left)) 307 { 308 x = y; 309 y = y->parent; 310 } 311 312 return y; 313 } 314 315 /* 316 * 将结点插入到二叉树中 317 * 318 * 参数说明: 319 * tree 二叉树的根结点 320 * z 插入的结点 321 */ 322 template <class T> 323 void BSTree<T>::insert(BSTNode<T>* &tree, BSTNode<T>* z) 324 { 325 BSTNode<T> *y = NULL; 326 BSTNode<T> *x = tree; 327 328 // 查找z的插入位置 329 while (x != NULL) 330 { 331 y = x; 332 if (z->key < x->key) 333 x = x->left; 334 else 335 x = x->right; 336 } 337 338 z->parent = y; 339 if (y==NULL) 340 tree = z; 341 else if (z->key < y->key) 342 y->left = z; 343 else 344 y->right = z; 345 } 346 347 /* 348 * 将结点(key为节点键值)插入到二叉树中 349 * 350 * 参数说明: 351 * tree 二叉树的根结点 352 * key 插入结点的键值 353 */ 354 template <class T> 355 void BSTree<T>::insert(T key) 356 { 357 BSTNode<T> *z=NULL; 358 359 // 如果新建结点失败,则返回。 360 if ((z=new BSTNode<T>(key,NULL,NULL,NULL)) == NULL) 361 return ; 362 363 insert(mRoot, z); 364 } 365 366 /* 367 * 删除结点(z),并返回被删除的结点 368 * 369 * 参数说明: 370 * tree 二叉树的根结点 371 * z 删除的结点 372 */ 373 template <class T> 374 BSTNode<T>* BSTree<T>::remove(BSTNode<T>* &tree, BSTNode<T> *z) 375 { 376 BSTNode<T> *x=NULL; 377 BSTNode<T> *y=NULL; 378 379 if ((z->left == NULL) || (z->right == NULL) ) 380 y = z; 381 else 382 y = successor(z); 383 384 if (y->left != NULL) 385 x = y->left; 386 else 387 x = y->right; 388 389 if (x != NULL) 390 x->parent = y->parent; 391 392 if (y->parent == NULL) 393 tree = x; 394 else if (y == y->parent->left) 395 y->parent->left = x; 396 else 397 y->parent->right = x; 398 399 if (y != z) 400 z->key = y->key; 401 402 return y; 403 } 404 405 /* 406 * 删除结点(z),并返回被删除的结点 407 * 408 * 参数说明: 409 * tree 二叉树的根结点 410 * z 删除的结点 411 */ 412 template <class T> 413 void BSTree<T>::remove(T key) 414 { 415 BSTNode<T> *z, *node; 416 417 if ((z = search(mRoot, key)) != NULL) 418 if ( (node = remove(mRoot, z)) != NULL) 419 delete node; 420 } 421 422 /* 423 * 销毁二叉树 424 */ 425 template <class T> 426 void BSTree<T>::destroy(BSTNode<T>* &tree) 427 { 428 if (tree==NULL) 429 return ; 430 431 if (tree->left != NULL) 432 return destroy(tree->left); 433 if (tree->right != NULL) 434 return destroy(tree->right); 435 436 delete tree; 437 tree=NULL; 438 } 439 440 template <class T> 441 void BSTree<T>::destroy() 442 { 443 destroy(mRoot); 444 } 445 446 /* 447 * 打印"二叉查找树" 448 * 449 * key -- 节点的键值 450 * direction -- 0,表示该节点是根节点; 451 * -1,表示该节点是它的父结点的左孩子; 452 * 1,表示该节点是它的父结点的右孩子。 453 */ 454 template <class T> 455 void BSTree<T>::print(BSTNode<T>* tree, T key, int direction) 456 { 457 if(tree != NULL) 458 { 459 if(direction==0) // tree是根节点 460 cout << setw(2) << tree->key << " is root" << endl; 461 else // tree是分支节点 462 cout << setw(2) << tree->key << " is " << setw(2) << key << "'s " << setw(12) << (direction==1?"right child" : "left child") << endl; 463 464 print(tree->left, tree->key, -1); 465 print(tree->right,tree->key, 1); 466 } 467 } 468 469 template <class T> 470 void BSTree<T>::print() 471 { 472 if (mRoot != NULL) 473 print(mRoot, mRoot->key, 0); 474 } 475 476 #endif 477 main.cpp 478 479 /** 480 * C++ 语言: 二叉查找树 481 * 482 * @author skywang 483 * @date 2013/11/07 484 */ 485 486 #include <iostream> 487 #include "BSTree.h" 488 using namespace std; 489 490 static int arr[]= {1,5,4,3,2,6}; 491 #define TBL_SIZE(a) ( (sizeof(a)) / (sizeof(a[0])) ) 492 493 int main() 494 { 495 int i, ilen; 496 BSTree<int>* tree=new BSTree<int>(); 497 498 cout << "== 依次添加: "; 499 ilen = TBL_SIZE(arr); 500 for(i=0; i<ilen; i++) 501 { 502 cout << arr[i] <<" "; 503 tree->insert(arr[i]); 504 } 505 506 cout << "\n== 前序遍历: "; 507 tree->preOrder(); 508 509 cout << "\n== 中序遍历: "; 510 tree->inOrder(); 511 512 cout << "\n== 后序遍历: "; 513 tree->postOrder(); 514 cout << endl; 515 516 cout << "== 最小值: " << tree->minimum() << endl; 517 cout << "== 最大值: " << tree->maximum() << endl; 518 cout << "== 树的详细信息: " << endl; 519 tree->print(); 520 521 cout << "\n== 删除根节点: " << arr[3]; 522 tree->remove(arr[3]); 523 524 cout << "\n== 中序遍历: "; 525 tree->inOrder(); 526 cout << endl; 527 528 // 销毁二叉树 529 tree->destroy(); 530 531 return 0; 532 }
标签:知识点,结点,BSTNode,tree,C++,二叉树,key,NULL 来源: https://www.cnblogs.com/fby698/p/14349614.html