【C++】实现的二叉搜索树BST

概念:

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树),二叉搜索树是一种特殊的二叉树

二叉搜索树的性质:

1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。
2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
4. 左右子树都是二叉搜索树

根据二叉搜索树的性质知:对二叉搜索树进行中序遍历得到的结点序列必然是一个有序序列。


接下来用C++代码实现搜索二叉树,若有错误或不足之处,还望各位大神指点。。。

代码:(代码中间包含了对基本功能(插入,删除,查找)的递归和非递归的实现)

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">include <iostream>  
  2. #include <string>  
  3. using namespace std;  
  4.   
  5. template<class K,class V>  
  6. struct BSTreeNode  
  7. {  
  8.     K _data;            //值  
  9.     V _freq;                //出现的频率  
  10.   
  11.     BSTreeNode<K, V>* _left;      //指向左子树的指针  
  12.     BSTreeNode<K, V>* _right;     //指向右子树的指针  
  13.   
  14.     BSTreeNode(const K& data, const V& freq)//初始化  
  15.         :_data(data)  
  16.         , _freq(freq)  
  17.         , _left(NULL)  
  18.         , _right(NULL)  
  19.     {}  
  20. };  
  21. template<class K, class V>  
  22. struct BSTree  
  23. {  
  24.     typedef BSTreeNode<K, V> Node;  
  25. public:  
  26.     BSTree()//初始化  
  27.         :_root(NULL)  
  28.     {}  
  29.     //插入  
  30.     bool Insert(const K& data, const V& freq)  
  31.     {  
  32.         if (_root == NULL)//如果节点为空,就在此节点处加入data数据  
  33.         {  
  34.             _root = new Node(data, freq);  
  35.             return true;  
  36.         }  
  37.   
  38.         Node* parent = NULL;  
  39.         Node* cur = _root;  
  40.         while (cur)//搜索data应该插入的节点:parent节点后  
  41.         {  
  42.             if (data > cur->_data)//如果data大于节点的值,就继续在节点的右子树中插入data  
  43.             {  
  44.                 parent = cur;  
  45.                 cur = cur->_right;  
  46.             }  
  47.             else if (data < cur->_data)//如果data小于节点的值,就继续在节点的左子树中插入data  
  48.             {  
  49.                 parent = cur;  
  50.                 cur = cur->_left;  
  51.             }  
  52.             else  
  53.             {  
  54.                 cur->_freq++;  
  55.                 return true;  
  56.             }  
  57.         }  
  58.         //在parent节点后插入data  
  59.         if (data > parent->_data)  
  60.         {  
  61.             parent->_right = new Node(data, freq);  
  62.         }  
  63.         else  
  64.         {  
  65.             parent->_left = new Node(data, freq);  
  66.         }  
  67.         return true;  
  68.     }  
  69.     Node* Find(const K& data)//查找  
  70.     {  
  71.         Node* cur = _root;  
  72.         while (cur)  
  73.         {  
  74.             if (data >cur->_data)//若data大于当前节点,则在当前节点的右子树中查找  
  75.             {  
  76.                 cur = cur->_right;  
  77.             }  
  78.             else if (data < cur->_data)//若data小于当前节点,则在当前节点的左子树中查找  
  79.             {  
  80.                 cur = cur->_left;  
  81.             }  
  82.             else  
  83.             {  
  84.                 return cur;  
  85.             }  
  86.         }  
  87.         return NULL;  
  88.     }  
  89.     bool Remove(const K& data)//删除  
  90.     {  
  91.         Node* parent = NULL;  
  92.         Node* cur = _root;  
  93.   
  94.         while (cur)//寻找data节点cur  
  95.         {  
  96.             if (data > cur->_data)  
  97.             {  
  98.                 parent = cur;  
  99.                 cur = cur->_right;  
  100.             }  
  101.             else if (data < cur->_data)  
  102.             {  
  103.                 parent = cur;  
  104.                 cur = cur->_left;  
  105.             }  
  106.             else//要么cur==NULL退出了循环,要么data==cur->_databreak  
  107.             {  
  108.                 break;  
  109.             }  
  110.         }  
  111.   
  112.         if (cur == NULL)  
  113.         {  
  114.             return false;  
  115.         }  
  116.   
  117.         //1.左为空,或者右为空  
  118.         //2.左右都不为空  
  119.         if (cur->_left == NULL)  
  120.         {//cur的左为空  
  121.             if (parent == NULL)//删除的是根节点  
  122.             {  
  123.                 _root = cur->_right;  
  124.             }  
  125.             else  
  126.             {  
  127.                 if (parent->_left == cur)  
  128.                 {  
  129.                     parent->_left = cur->_right;  
  130.                 }  
  131.                 else  
  132.                 {  
  133.                     parent->_right = cur->_right;  
  134.                 }  
  135.             }  
  136.           
  137.             delete cur;  
  138.         }  
  139.         else if (cur->_right == NULL)  
  140.         {//cur的右为空  
  141.             if (parent == NULL)  
  142.             {  
  143.                 _root = cur->_right;  
  144.             }  
  145.             else  
  146.             {  
  147.                 if (parent->_left == cur)  
  148.                 {  
  149.                     parent->_left = cur->_left;  
  150.                 }  
  151.                 else  
  152.                 {  
  153.                     parent->_right = cur->_left;  
  154.                 }  
  155.             }  
  156.             delete cur;  
  157.         }  
  158.         else  
  159.         {//左不为空,右也不为空  
  160.             parent = cur;  
  161.             Node *subLeft = cur->_right;//subarea node  子区节点  
  162.             while (subLeft->_left)  
  163.             {//遍历删除节点的左子树??  
  164.                 parent = subLeft;  
  165.                 subLeft = subLeft->_left;  
  166.             }  
  167.             cur->_data = subLeft->_data;  
  168.             cur->_freq = subLeft->_freq;  
  169.   
  170.             if (parent->_left == subLeft)  
  171.             {  
  172.                 parent->_left = subLeft->_right;  
  173.             }  
  174.             else  
  175.             {  
  176.                 parent->_right = subLeft->_right;  
  177.             }  
  178.             delete subLeft;  
  179.         }  
  180.         return true;  
  181.     }  
  182.   
  183.     //以下是递归方式  
  184.     bool InsertR(const K& data, const V& freq)  
  185.     {  
  186.         return _InsertR(_root, data, freq);  
  187.     }  
  188.     bool _InsertR(Node*& root, const K& data, const V& freq)  
  189.     {  
  190.         if (root == NULL)  
  191.         {  
  192.             root = new Node(key, freq);  
  193.             return true;  
  194.         }  
  195.   
  196.         if (data > root->_data)  
  197.         {  
  198.             return _InsertR(root->_right, key, freq);  
  199.         }  
  200.         else if (data < root->_data)  
  201.         {  
  202.             return _InsertR(root->_left, key, freq);  
  203.         }  
  204.         else  
  205.         {  
  206.             return false;  
  207.         }  
  208.     }  
  209.     Node* FindR(const K& data)  
  210.     {  
  211.         return _FindR(_root, data);  
  212.     }  
  213.     Node* _FindR(Node*& root, const K& data)  
  214.     {  
  215.         if (root == NULL)  
  216.         {  
  217.             return NULL;  
  218.         }  
  219.   
  220.         if (data > root->_data)  
  221.         {  
  222.             return _FindR(root->_right, key);  
  223.         }  
  224.         else if (data < root->_data)  
  225.         {  
  226.             return _FindR(root->_left, key);  
  227.         }  
  228.         else  
  229.         {  
  230.             return root;  
  231.         }  
  232.     }  
  233.   
  234.     bool RemoveR(const K& data)  
  235.     {  
  236.         return _RemoveR(_root, data);  
  237.     }  
  238.     bool _RemoveR(Node*& root, const K& data)  
  239.     {  
  240.         if (root == NULL)  
  241.         {  
  242.             return false;  
  243.         }  
  244.         if (data > root->_data)  
  245.         {  
  246.             return _RemoveR(root->_right, data);  
  247.         }  
  248.         else if (data < root->_data)  
  249.         {  
  250.             return _RemoveR(root->_left, data);  
  251.         }  
  252.         else  
  253.         {  
  254.             Node* del = root;  
  255.             if (root->_left == NULL)  
  256.             {  
  257.                 root = root->_right;  
  258.             }  
  259.             else if (root->_right == NULL)  
  260.             {  
  261.                 root = root->_left;  
  262.             }  
  263.             else  
  264.             {  
  265.                 Node* parent = root;  
  266.                 Node* subLeft = root->_right;  
  267.                 while (subLeft->_left)  
  268.                 {  
  269.                     parent = subLeft;  
  270.                     subLeft = subLeft->_left;  
  271.                 }  
  272.                 root->_data = subLeft->_data;  
  273.                 root->_freq = subLeft->_freq;  
  274.   
  275.                 del = subLeft;  
  276.   
  277.                 if (parent->_left == subLeft)  
  278.                 {  
  279.                     parent->_left = subLeft->_right;  
  280.                 }  
  281.                 else  
  282.                 {  
  283.                     parent->_right = subLeft->_right;  
  284.                 }  
  285.             }  
  286.             delete del;  
  287.             return true;  
  288.         }  
  289.     }  
  290.   
  291.     void InOrder()  
  292.     {  
  293.         _InOrder(_root);  
  294.         cout << endl;  
  295.     }  
  296.     void _InOrder(Node* root)  
  297.     {  
  298.         if (root == NULL)  
  299.             return;  
  300.   
  301.         _InOrder(root->_left);  
  302.         cout << root->_data << " ";  
  303.         _InOrder(root->_right);  
  304.     }  
  305. protected:  
  306.     Node* _root;  
  307. };</span>  

在删除算法过程中要注意细节情况

1.删除根节点

2.删除叶子节点

3.删除带有子树的节点


算法分析:

它和二分查找一样,插入和查找的时间复杂度均为lgN,但是在最坏的情况下仍然会有N的时间复杂度。原因在于插入和删除元素的时候,树没有保持平衡。我们追求的是在最坏的情况下仍然有较好的时间复杂度,这就是后面要讲的平衡查找树的内容了。下文首先讲解平衡查找树的最简单的一种:2-3查找树。

BST与二分查找一样,插入与查找的时间复杂度均为lgN,但是BST最坏情况是插入一个本身的有序的数列,这样在构建BST时会退化成类似于数组结构

即:



有一篇BST分析的很到位,链接是:

http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html

所以也就衍生出AVL树即平衡二叉查找树

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值