二叉查找树

二叉查找树(Binary Search Tree),或者是一棵空树,或者是具有下列性质的查找树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉查找树

中序周游二叉排序树可得到一个升序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子节点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,O(log(n)).

二叉查找树是二叉树的一个特例,因此我们继承至上篇二叉树,具体代码如下:

BinarySearchTree.h

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #ifndef BIANRY_SEARCH_TREE_H  
  2. #define BINARY_SEARCH_TREE_H  
  3.   
  4. template <typename T>  
  5. class BinarySearchTree : public BinaryTree<T>  
  6. {  
  7. public:  
  8.       
  9.   
  10.     void initialize(BinaryTreeNode<T> *newPoint)  
  11.     {  
  12.         root = newPoint;  
  13.     }  
  14.   
  15.     /************************************************************************/  
  16.     /* 从根节点开始查找,newpointer若小于当前节点,则沿左路下降,当当前节点的 
  17.     左孩子为空时,作为其左孩子插入;newpointer若大于当前节点,则沿右节点下降,当 
  18.     当前节点的右孩子为空时,作为其右孩子插入                               */  
  19.     /************************************************************************/  
  20.     void insertNode(BinaryTreeNode<T> *root,BinaryTreeNode<T> *newpointer)  
  21.     {  
  22.         BinaryTreeNode<T> *pointer = nullptr;  
  23.         if(root == nullptr)//如果是空树,初始化  
  24.         {  
  25.             initialize(newpointer);//用指针newpointer初始化二叉搜索树树根,赋值实现  
  26.             return;  
  27.         }  
  28.         else  
  29.         {  
  30.             pointer = root;  
  31.         }  
  32.   
  33.         while(true)  
  34.         {  
  35.             if(newpointer->value() == pointer->value())  
  36.             {  
  37.                 return;//相等则不用插入  
  38.             }  
  39.   
  40.             if(newpointer->value() < pointer->value())  
  41.             {  
  42.                 if(pointer->leftChild() == nullptr)  
  43.                 {  
  44.                     pointer->setLeftChild(newpointer);//作为左子树  
  45.                     return;  
  46.                 }  
  47.                 else  
  48.                 {  
  49.                     pointer = pointer->leftChild();//作为右子树  
  50.                 }  
  51.             }  
  52.   
  53.             if(newpointer->value() > pointer->value())  
  54.             {  
  55.                 if(pointer->rightChild() == nullptr)  
  56.                 {  
  57.                     pointer->setRightChild(newpointer);  
  58.                     return;  
  59.                 }  
  60.                 else  
  61.                 {  
  62.                     pointer = pointer->rightChild();  
  63.                 }  
  64.             }  
  65.         }  
  66.     }  
  67.   
  68.     /************************************************************************/  
  69.     /*删除节点过程如下:若pointer的左孩子为空,则用pointer的右孩子的节点代替pointer; 
  70.     若pointer的左孩子不为空,则在pointer的左子树中按中序周游找到最后一个节点temppointer 
  71.     ,把temppointer的右指针设置为pointer右孩子的根,pointer左孩子的根代替被删除的节 
  72.     点pointer, 
  73.     弊端:有可能使树的高度增加*/  
  74.     /************************************************************************/  
  75.     void deleteNode(BinaryTreeNode<T> *pointer)  
  76.     {  
  77.         BinaryTreeNode<T> *temppointer = nullptr;  
  78.         if(!pointer)  
  79.         {  
  80.             return;  
  81.         }  
  82.   
  83.         BinaryTreeNode<T> *parenter = parent(pointer);  
  84.   
  85.         //被删结点无左子树,则将其右子树的根代替该删除结点  
  86.         if(pointer->leftChild() == nullptr)  
  87.         {  
  88.             if(parenter == nullptr)//删除的是根节点  
  89.             {  
  90.                 root = pointer->rightChild();  
  91.                   
  92.             }  
  93.             else if(parenter->leftChild() == pointer)  
  94.             {  
  95.                 parenter->setLeftChild(pointer->rightChild());  
  96.                   
  97.             }  
  98.             else  
  99.             {  
  100.                 parenter->setRightChild(parenter->rightChild()) ;  
  101.                   
  102.             }  
  103.   
  104.             delete pointer;//删除该节点  
  105.             pointer = nullptr;  
  106.             return;  
  107.         }  
  108.   
  109.         else//有左子树的情况  
  110.         {  
  111.             temppointer = pointer->leftChild();  
  112.             while(temppointer->rightChild() != nullptr)  
  113.             {  
  114.                 temppointer = temppointer->rightChild();  
  115.             }  
  116.   
  117.             //被删除结点的右子树作为temppointer的右子树  
  118.             temppointer->setRightChild(pointer->rightChild());  
  119.   
  120.             if(parenter == nullptr)//删除的是根节点  
  121.             {  
  122.                 root = pointer->leftChild();  
  123.   
  124.             }  
  125.   
  126.             //pointer左孩子的根代替被删除的节点pointer  
  127.             else if(parenter->leftChild() == pointer)  
  128.             {  
  129.                 parenter->setLeftChild(pointer->leftChild());  
  130.   
  131.             }  
  132.             else  
  133.             {  
  134.                 parenter->setRightChild(pointer->leftChild()) ;  
  135.   
  136.             }  
  137.   
  138.             delete pointer;//删除该节点  
  139.             pointer = nullptr;  
  140.             return;  
  141.         }  
  142.     }  
  143.   
  144.     /************************************************************************/  
  145.     /*为了克服上个删除算法可能使树高度增加的弊端,新的删除节点过程如下: 
  146.     若pointer的左孩子为空,则用pointer的右孩子的节点代替pointer; 
  147.     若pointer的左孩子不为空,则在pointer的左子树中按中序周游找到最后一个节点  
  148.     temppointer,temppointer左孩子的根代替temppointer,把temppointer代替pointer  */  
  149.     /************************************************************************/  
  150.   
  151.     void deleteNodeEx(BinaryTreeNode<T> *pointer)  
  152.     {  
  153.         BinaryTreeNode<T> *temppointer = nullptr;// 用于保存替换结点  
  154.         BinaryTreeNode<T> *tempparent = nullptr;// 用于保存替换结点的父结点  
  155.         if(!pointer)  
  156.         {  
  157.             return;  
  158.         }  
  159.   
  160.         BinaryTreeNode<T> *parenter = parent(pointer);// 保存删除结点的父结点  
  161.   
  162.         //被删结点无左子树,则将其右子树的根代替该删除结点  
  163.         if(pointer->leftChild() == nullptr)  
  164.         {  
  165.             if(parenter == nullptr)//删除的是根节点  
  166.             {  
  167.                 root = pointer->rightChild();  
  168.   
  169.             }  
  170.             else if(parenter->leftChild() == pointer)  
  171.             {  
  172.                 parenter->setLeftChild(pointer->rightChild());  
  173.   
  174.             }  
  175.             else  
  176.             {  
  177.                 parenter->setRightChild(parenter->rightChild()) ;  
  178.   
  179.             }  
  180.   
  181.             delete pointer;//删除该节点  
  182.             pointer = nullptr;  
  183.             return;  
  184.         }  
  185.   
  186.         else//有左子树的情况  
  187.         {  
  188.             temppointer = pointer->leftChild();  
  189.             while(temppointer->rightChild() != nullptr)  
  190.             {  
  191.                 tempparent = temppointer;  
  192.                 temppointer = temppointer->rightChild();  
  193.             }  
  194.               
  195.             if(tempparent == nullptr)//替换节点就是被删除节点的左子节点,如果不处理此处边界情况,则tempparent为空,tempparent->setRightChild(temppointer->leftChild())无法执行  
  196.             {  
  197.                 //替换节点左子树挂接到被删除节点的左子树,其实也就是temppointer左孩子的根代替temppointer  
  198.                 pointer->setLeftChild(temppointer->leftChild());  
  199.             }  
  200.               
  201.             else  
  202.             {  
  203.                 //temppointer左孩子的根代替temppointer  
  204.                 tempparent->setRightChild(temppointer->leftChild());  
  205.             }  
  206.               
  207.             //将pointer的左右子树挂到temppointer下面  
  208.             temppointer->setLeftChild(pointer->leftChild());  
  209.             temppointer->setRightChild(pointer->rightChild());  
  210.   
  211.   
  212.             if(parenter == nullptr)//删除的是根节点  
  213.             {  
  214.                 root = pointer->leftChild();  
  215.   
  216.             }  
  217.             //temppointer代替被删除的节点pointer  
  218.             else if(parenter->leftChild() == pointer)  
  219.             {  
  220.                 parenter->setLeftChild(temppointer);  
  221.   
  222.             }  
  223.             else  
  224.             {  
  225.                 parenter->setRightChild(temppointer) ;  
  226.   
  227.             }  
  228.   
  229.             delete pointer;//删除该节点  
  230.             pointer = nullptr;  
  231.             return;  
  232.         }  
  233.     }  
  234. };  
  235. #endif  
测试代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "BinaryTree.h"  
  2. #include "BinarySearchTree.h"  
  3. #include <iostream>  
  4.   
  5. const int N = 11;  
  6.   
  7.   
  8. int main()  
  9. {  
  10.     int K[N] = {50,19,35,55,20,5,100,52,88,53,92};        //建一棵图5.11所示的树,见北大张铭《数据结构与算法》  
  11.     BinarySearchTree<int> aBST;  
  12.     BinaryTreeNode<int > *newpointer, *node1, *node2;     // 循环插入结点  
  13.   
  14.     for (int i = 0; i < N; i ++)  {                         
  15.         newpointer = new BinaryTreeNode<int>();  
  16.         newpointer->setValue(K[i]);  
  17.         aBST.insertNode(aBST.getRoot(), newpointer);      //依次插入结点  
  18.   
  19.         if (K[i] == 52){                                //记录待删除结点的指针node1  
  20.             node1 = newpointer;  
  21.             //   cout<<node1->value()<<endl;  
  22.         }  
  23.         if (K[i] == 55)                                 //记录待删除结点的指针node2  
  24.             node2 = newpointer;   
  25.     }  
  26.   
  27.     // 遍历结点  
  28.     cout << "中序周游二叉搜索树:" << endl;  
  29.     aBST.inOrder(aBST.getRoot());  
  30.     cout << endl;   
  31.   
  32.     //删除两个结点                                   
  33.     cout << "删除结点52, 55." << endl;  
  34.     //aBST.deleteNodeEx(node1);  
  35.     aBST.deleteNodeEx(node2);   
  36.   
  37.   
  38.   
  39.     // 遍历节点  
  40.     cout << "删除结点之后中序周游二叉搜索树:" << endl;   
  41.     aBST.inOrder(aBST.getRoot());  
  42.     cout << endl;  
  43.   
  44.     system("pause");  
  45.     return 0;  
  46. }  

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值