1 #include <iostream> 2 #include <stack> 3 using namespace std; 4 5 template<typename T> 6 struct BinaryNode 7 { 8 T element; 9 BinaryNode<T> *left; 10 BinaryNode<T> *right; 11 12 BinaryNode(const T &theElement, BinaryNode *lt, BinaryNode *rt) 13 : element(theElement), left(lt), right(rt) {} 14 }; 15 16 17 template<typename T> 18 class BinarySearchTree 19 { 20 public: 21 BinarySearchTree() { 22 root = nullptr; 23 } 24 BinarySearchTree(const BinarySearchTree& rhs) { //复制构造函数 25 root = clone(rhs.root); 26 } 27 ~BinarySearchTree(); 28 29 const T &findMin() const { 30 return findMin(root)->element; 31 } 32 const T &findMax() const { 33 return findMax(root)->element; 34 } 35 36 bool contains(const T& x) const; 37 T& getNode(const T& e) { //得到元素为e的结点 38 return getNode(e, root)->element; 39 } 40 41 bool isEmpty() const { 42 if (root == nullptr) 43 return true; 44 return false; 45 } 46 void PreprintTree() const { 47 PreprintTree(root); 48 } 49 50 void InprintTree() const { 51 InprintTree(root); 52 } 53 54 void PostprintTree() const { 55 PostprintTree(root); 56 } 57 58 void LevelprintTree() const { 59 LevelprintTree(root); 60 } 61 62 void PreprintTree_N() const { 63 PreprintTree_N(root); 64 } 65 66 void InprintTree_N() const { 67 InprintTree_N(root); 68 } 69 70 void PostprintTree_N() const { 71 PostprintTree_N(root); 72 } 73 74 void DisplayTreeShape(int level = 1) const { 75 DisplayTreeShape(root, level); 76 } 77 78 void makeEmpty(); 79 void insert(const T &x); 80 void remove(const T &x); 81 int Depth(); 82 int CountLeaf() { 83 BinaryNode<T> *p = root; 84 int count = 0; 85 CountLeaf(p, count); 86 return count; 87 } 88 89 const BinarySearchTree& operator = (const BinarySearchTree& rhs); 90 91 private: 92 93 BinaryNode<T> *root; //指向树根结点的指针 94 95 void insert(const T & x, BinaryNode<T> * & t); 96 void remove(const T & x, BinaryNode<T> * & t); 97 BinaryNode<T> * findMin(BinaryNode<T> *t) const; 98 BinaryNode<T> * findMax(BinaryNode<T> *t ) const; 99 100 bool contains(const T & x, BinaryNode<T> *t) const; 101 BinaryNode<T> * getNode(const T &x, BinaryNode<T> *t); 102 103 void makeEmpty( BinaryNode<T> * & t ); 104 //利用 递归 算法 计算树的 深度 105 int Depth( BinaryNode<T> * t, int level, int &depth); 106 //利用 递归 算法 计算树的 高度 107 void CountLeaf(BinaryNode<T> * t, int &count); 108 109 110 void PreprintTree( BinaryNode<T> * t ) const; //先序遍历 111 void InprintTree( BinaryNode<T> *t ) const; //中序遍历 112 void PostprintTree( BinaryNode<T> * t ) const; //后序遍历 113 void LevelprintTree( BinaryNode<T> * t) const; //层次遍历 114 115 void PreprintTree_N( BinaryNode<T> * t) const; //非递归先序遍历 116 void InprintTree_N( BinaryNode<T> * t) const; //非递归中序遍历二叉树 117 void PostprintTree_N( BinaryNode<T> * t) const; //非递归后序遍历二叉树 118 void DisplayTreeShape(BinaryNode<T> *bt, int level) const; //二叉树的树形显示算法 119 120 121 BinaryNode<T> * clone( BinaryNode<T> * t ) const; 122 }; 123 124 template<typename T> 125 bool BinarySearchTree<T>::contains(const T& x) const 126 { 127 return contains(x, root); 128 } 129 130 template<typename T> 131 bool BinarySearchTree<T>::contains(const T & x, BinaryNode<T> *t) const 132 { 133 if (t == nullptr) 134 return false; 135 else if (x < t->element) // x 小, 说明应该在左边找 136 return contains(x, t->left); 137 else if (t->element < x) // x 大, 说明应该在右面找 138 return contains(x, t->right); 139 else 140 return true; 141 } 142 143 template<typename T> 144 BinaryNode<T>* BinarySearchTree<T>::getNode(const T & x, BinaryNode<T> *t) 145 { 146 if (t == nullptr) 147 return nullptr; 148 else if (x < t->element) 149 return getNode(x, t->left); 150 else if (t->element < x) 151 return getNode(x, t->right); 152 return t; 153 } 154 155 156 //findMin--返回指向树中包含最小元的结点的指针 157 template<typename T> 158 BinaryNode<T> * BinarySearchTree<T>::findMin(BinaryNode<T> *t) const 159 { 160 if (t == nullptr) 161 return nullptr; 162 if (t->left == nullptr) 163 return t; 164 return findMin(t->left); 165 } 166 167 template<typename T> 168 BinaryNode<T>* BinarySearchTree<T>::findMax(BinaryNode<T> *t) const 169 { 170 if (t != nullptr) 171 while (t->right != nullptr) { 172 t = t->right; 173 } 174 return t; 175 } 176 177 template<typename T> 178 void BinarySearchTree<T>::insert(const T &x) 179 { 180 insert(x, root); 181 } 182 183 /************************************************************************/ 184 /* x is the item to insert */ 185 /* t is the node that roots the subtree*/ 186 /* Set the new root of the subtree*/ 187 ///* 只有当一个新树叶生成时候,t才改变. 188 ///* t 是到p->left或p->right的引用.==> 意味着p->left或p->right将会改变为指向新结点. 189 /************************************************************************/ 190 template<typename T> 191 void BinarySearchTree<T>::insert(const T & x, BinaryNode<T> * & t) 192 { 193 if (t == nullptr) //没有结点,在该位置处添加新结点 194 t = new BinaryNode<T>(x, nullptr, nullptr); 195 else if (x < t->element) //x 小, 在左子树查询 196 insert(x, t->left); 197 else if (t->element < x) //x 大, 在右子树查询 198 insert(x, t->right); 199 else; //Duplicate, do nothing; 200 } 201 202 template<typename T> 203 void BinarySearchTree<T>::remove(const T &x) 204 { 205 remove(x, root); 206 } 207 208 /************************************************************************/ 209 /* x is item to remove */ 210 /* t is the node that roots the subtree */ 211 /* Set the new root of the subtree */ 212 /* 1.结点是一片树叶时 -- 可被立即删除*/ 213 /* 2.结点有一个儿子, 则该结点可以在其父节点调整他的链 以绕过该结点后被删除 */ 214 /* 3.结点有两个儿子, 则其右子树的最小数据代替该结点的数据,并递归删除那个结点 */ 215 /* 注: 右子树中的最小的结点不可能有左结点 */ 216 /************************************************************************/ 217 template<typename T> 218 void BinarySearchTree<T>::remove(const T &x, BinaryNode<T> * & t) 219 { 220 if (t == nullptr) return; //Item not found; do nothing 221 if (x < t->element) //x 小,在左子树递归查找 222 remove(x, t->left); 223 else if (t->element < x) //x 大,在右子树递归查找 224 remove(x, t->right); 225 else if (t->left != nullptr && t->right != nullptr) //two children 226 { 227 //在右子树中查找最小数据代替该结点数据.; 228 t->element = findMin(t->right)->element; 229 remove(t->element, t->right); //删除该结点 230 } 231 else //只有一个结点或是树叶. 调整它的链,以绕过该结点后被删除. 232 { 233 BinaryNode<T> *oldNode = t; 234 t = (t->left != nullptr) ? t->left : t->right; 235 delete oldNode; 236 } 237 } 238 239 /************************************************************************/ 240 ///* Destructor for the tree 241 /************************************************************************/ 242 template<typename T> 243 BinarySearchTree<T>::~BinarySearchTree() 244 { 245 makeEmpty(); 246 } 247 248 template<typename T> 249 void BinarySearchTree<T>::makeEmpty() //公有函数 250 { 251 makeEmpty(root); 252 } 253 254 /************************************************************************/ 255 ///* Internal method to make subtree empty -- 私有函数 256 /************************************************************************/ 257 template<typename T> 258 void BinarySearchTree<T>::makeEmpty(BinaryNode<T> * & t) 259 { 260 if (t != nullptr) 261 { 262 makeEmpty(t->left); 263 makeEmpty(t->right); 264 delete t; 265 } 266 t = nullptr; 267 } 268 269 /************************************************************************/ 270 ///* Deep copy 271 /************************************************************************/ 272 template<typename T> 273 const BinarySearchTree<T>& BinarySearchTree<T>::operator = (const BinarySearchTree &rhs) 274 { 275 if (this != &rhs) { 276 makeEmpty(); 277 root = clone(rhs.root); 278 } 279 return *this; 280 } 281 282 /************************************************************************/ 283 ///* Internal method to clone subtree. -- 递归复制结点 284 /************************************************************************/ 285 template<typename T> 286 BinaryNode<T>* BinarySearchTree<T>::clone(BinaryNode<T> * t) const 287 { 288 if (t == nullptr) 289 return nullptr; 290 return new BinaryNode<T>( t->element, clone(t->left), clone(t->right) ); 291 } 292 293 //利用递归计算树的深度 294 template<typename T> 295 int BinarySearchTree<T>::Depth() 296 { 297 BinaryNode<T> *t = root; 298 int depth = 0; 299 if (root == nullptr) 300 return 0; 301 Depth(t, 1, depth); 302 return depth; 303 } 304 305 //由public的函数Depth调用, 完成树的深度的计算,p是根结点,Level是层,depth用来返回树的深度 306 template<typename T> 307 int BinarySearchTree<T>::Depth(BinaryNode<T> *t, int level, int &depth) 308 { 309 if (level > depth) depth = level; //层数 310 if (t->left) Depth(t->left, level + 1, depth); //递归遍历左子树,且层数加1 311 if (t->right) Depth(t->right, level + 1, depth); //递归遍历右子树, 且层数加1 312 return 0; 313 } 314 315 template<typename T> 316 //利用 递归 算法 计算树的 高度 317 void BinarySearchTree<T>::CountLeaf(BinaryNode<T> * t, int &count) 318 { 319 if (t == nullptr) return; //为空时,退出 320 321 // CountLeaf(t->left, count); 322 // CountLeaf(t->right, count); 323 if (!(t->left) && !(t->right)) { //儿子为空时 324 count++; 325 } 326 CountLeaf(t->left, count); 327 CountLeaf(t->right, count); 328 } 329 330 331 /************************************************************************/ 332 ///* printTree --- 前序遍历 333 /************************************************************************/ 334 template<typename T> 335 void BinarySearchTree<T>::PreprintTree(BinaryNode<T> * t) const 336 { 337 if (t != nullptr) { 338 cout << t->element << ' '; 339 PreprintTree(t->left); 340 PreprintTree(t->right); 341 } 342 } 343 344 //中序遍历 345 template<typename T> 346 void BinarySearchTree<T>::InprintTree(BinaryNode<T> * t ) const 347 { 348 if (t != nullptr) { 349 InprintTree(t->left); 350 cout << t->element << ' '; 351 InprintTree(t->right); 352 } 353 } 354 355 //后序遍历 356 template<typename T> 357 void BinarySearchTree<T>::PostprintTree(BinaryNode<T> * t) const 358 { 359 if (t != nullptr) { 360 PostprintTree(t->left); 361 PostprintTree(t->right); 362 cout << t->element << ' '; 363 } 364 } 365 366 //利用队列Queue层次遍历二叉树 367 template<typename T> 368 void BinarySearchTree<T>::LevelprintTree( BinaryNode<T> * t) const 369 { 370 const int maxn = 1024; 371 BinaryNode<T> *Queue[maxn]; //一维数组作为队列 372 BinaryNode<T> *tmp; 373 int front = 0, rear = 0; //队列初始为空 374 if (root) { 375 Queue[rear++] = root; //二叉树的根结点指针入队列 376 while (front != rear) 377 { 378 tmp = Queue[front++]; //队首的元素出队列 379 if (tmp) cout << tmp->element << ' '; //输出结点值 380 if (tmp->left) Queue[rear++] = tmp->left; 381 if (tmp->right) Queue[rear++] = tmp->right; 382 } 383 } 384 } 385 386 //先序遍历 387 template<typename T> 388 void BinarySearchTree<T>::PreprintTree_N( BinaryNode<T> * t) const //非递归先序遍历 389 { 390 const int maxn = 1024; 391 BinaryNode<T> *Stack[maxn]; 392 int top = 0; 393 BinaryNode<T> *tmp = root; //将根结点的指针赋值给tmp 394 395 // cout << "Debug : "; 396 while (tmp || top != 0) 397 { 398 // cout << "debug : "; 399 while (tmp) { 400 cout << tmp->element << ' '; 401 Stack[top++] = tmp; //右孩子入栈 402 tmp = tmp->left; //一直递归到最左的结点 403 } 404 if (top) { //栈不为空, 从栈中取出一个结点指针 405 tmp = Stack[--top]; 406 tmp = tmp->right; 407 } 408 } 409 } 410 411 //中序非递归遍历二叉树 (LDR) 412 template<typename T> 413 void BinarySearchTree<T>::InprintTree_N( BinaryNode<T> * t) const //非递归中序遍历二叉树 414 { 415 const int maxn = 1024; 416 BinaryNode<T> *Stack[maxn]; 417 int top = 0; 418 BinaryNode<T> *tmp = root; 419 420 while (tmp || top != 0) 421 { 422 while (tmp) { //迭代到最左的子树 423 Stack[top++] = tmp; //左子树入栈 424 tmp = tmp->left; 425 } 426 if (top) { 427 tmp = Stack[--top]; //出栈最左的子树 428 cout << tmp->element << ' '; //输出该元素 429 tmp = tmp->right; //并指向右结点开始迭代 430 } 431 } 432 433 } 434 435 //非递归后序遍历二叉树 (LRD) 436 template<typename T> 437 void BinarySearchTree<T>::PostprintTree_N( BinaryNode<T> * t) const 438 { 439 const int maxn = 1024; 440 struct Mystack { 441 BinaryNode<T> * link; 442 int flag; 443 }; 444 445 Mystack Stack[maxn]; 446 BinaryNode<T> * p = root, *tmp; 447 448 if (root == nullptr) return; 449 450 int top = -1, //栈顶初始化 451 sign = 0; //为结点tmp 的标志量 452 453 while ( p != nullptr || top != -1) 454 { 455 while (p != nullptr) //遍历到最左 456 { 457 Stack[++top].link = p; //并且一直入栈 458 Stack[top].flag = 1; //设置flag为第一次入栈 459 p = p->left; 460 } 461 462 if (top != -1) 463 { 464 tmp = Stack[top].link; 465 sign = Stack[top].flag; 466 top--; //出栈 467 468 if (sign == 1) //结点第一次进栈 469 { 470 top++; 471 Stack[top].link = tmp; 472 Stack[top].flag = 2; //标记为第二次出栈 473 p = tmp->right; 474 } 475 else { //第二次出栈就输出 476 cout << tmp->element << ' '; //访问该结点数据域 477 p = nullptr; 478 } 479 } 480 481 } 482 483 } 484 485 //树形显示二叉树,也是中序遍历 486 template<typename T> 487 void BinarySearchTree<T>::DisplayTreeShape(BinaryNode<T> *bt, int level) const 488 { 489 if (bt) //二叉树的树形显示算法 490 { 491 cout << endl; 492 for (int i = 0; i < level - 1; i++) 493 cout << " "; //确保在第level列显示结点 494 cout << bt->element; //显示结点 495 DisplayTreeShape(bt->left, level - 1); //空二叉树不显示 496 // cout << endl; //显示右子树 497 DisplayTreeShape(bt->right, level + 2); //显示左子树 498 } 499 } 500 501 int main() 502 { 503 // srand((unsigned)time(nullptr)); 504 int testData, t = 0; 505 BinarySearchTree<int> test; 506 cout << "输入数字个数: "; 507 cin >> t; 508 cout << "输入数字: "; 509 while (t--) 510 { 511 testData = rand() % 500 + 1; 512 test.insert(testData); 513 } 514 cout << " 全部元素为: "; 515 test.PreprintTree(); 516 517 cout << endl; 518 // cin >> testData; //不符合查找二叉树 519 // test.getNode(testData) = 10000; 520 521 522 cout << " Max = " << test.findMax() << endl; 523 cout << "Min = " << test.findMin() << endl; 524 525 cout << "输入查找元素: "; 526 cin >> testData; 527 cout << "是否包含 " << testData << " : " << test.contains(testData) << endl; 528 test.PreprintTree(); 529 530 cout << endl; 531 cout << "输入删除元素: "; 532 cin >> testData; 533 test.remove(testData); 534 535 cout << " 树的高度: " << test.Depth() << endl; 536 cout << " 叶子的个数: " << test.CountLeaf() << endl; 537 cout << endl; 538 539 cout << "先序遍历树元素: "; 540 test.PreprintTree(); 541 542 cout << " 中序遍历树元素: "; 543 test.InprintTree(); 544 545 cout << " 后序遍历树元素: "; 546 test.PostprintTree(); 547 548 cout << " 层次遍历树元素: "; 549 test.LevelprintTree(); 550 551 cout << " 先序遍历树元素(非递归): "; 552 test.PreprintTree_N(); 553 554 cout << " 中序遍历树元素(非递归): "; 555 test.InprintTree_N(); 556 557 cout << " 后序遍历树元素(非递归): "; 558 test.PostprintTree_N(); 559 560 cout << " 二叉树的树形显示算法: "; 561 test.DisplayTreeShape(43); 562 563 cout << endl; 564 return 0; 565 }