二叉搜索树的定义、查找、插入和删除

二叉搜索树的定义


二叉搜索树,也称有序二叉树,排序二叉树,是指一棵空树或者具有下列性质的二叉树:

1. 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

2. 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

3. 任意节点的左、右子树也分别为二叉查找树。

4. 没有键值相等的节点。


二叉搜索树的删除:

具体实现过程解析:

二叉搜索树的结构实现:

[cpp]  view plain  copy
  1. //二叉搜索树结构  
  2. template<class K, class V>  
  3. struct BSTreeNode  
  4. {  
  5.     BSTreeNode* _left;  
  6.     BSTreeNode* _right;  
  7.     K _key;  
  8.     V _value;  
  9.   
  10.     BSTreeNode(const K& key, const V& value)  
  11.         :_left(NULL)  
  12.         ,_right(NULL)  
  13.         ,_key(key)  
  14.         ,_value(value)  
  15.     {}  
  16.   
  17. };  

查找实现有迭代和递归两种

迭代法:

[cpp]  view plain  copy
  1.        //在二叉搜索树中查找节点  
  2. Node* Find(const K& key)  
  3. {  
  4.     Node* cur=_root;  
  5.     //开始遍历查找  
  6.     while (cur)  
  7.     {  
  8.         if (cur->_key > key)  
  9.         {  
  10.             cur = cur->_left;  
  11.         }  
  12.         else if(cur->_key<key)  
  13.         {  
  14.             cur = cur->_right;  
  15.         }  
  16.         else  
  17.         {  
  18.             return cur;  
  19.         }  
  20.     }  
  21.        
  22.     return NULL;  
  23. }  

递归法:

[cpp]  view plain  copy
  1.               //递归查找法  
  2. Node* _Find_R(Node* root, const K& key)  
  3. {  
  4.     if (root == NULL)  
  5.     {  
  6.         return NULL;  
  7.     }  
  8.     if (root->_key > key)  
  9.     {  
  10.         return _Find_R(root->_left, key);  
  11.     }  
  12.     else if (root->_key < key)  
  13.     {  
  14.         return _Find_R(root->_right, key);  
  15.     }  
  16.     else  
  17.     {  
  18.         return root;  
  19.     }  
  20. }  

删除迭代法:

[cpp]  view plain  copy
  1.        //在二叉搜索树中删除节点  
  2. bool Remove(const K& key)  
  3. {  
  4.     //没有节点  
  5.     if (_root == NULL)  
  6.     {  
  7.         return false;  
  8.     }  
  9.     //只有一个节点  
  10.     if (_root->_left == NULL&&_root->_right == NULL)  
  11.     {  
  12.         if (_root->_key == key)  
  13.         {  
  14.             delete _root;  
  15.             _root = NULL;  
  16.             return true;  
  17.         }  
  18.   
  19.         return false;  
  20.     }  
  21.   
  22.     Node* parent = NULL;  
  23.     Node* cur = _root;  
  24.     //遍历查找要删除节点的位置  
  25.     while (cur)  
  26.     {  
  27.         Node* del = NULL;  
  28.         if (cur->_key > key)  
  29.         {  
  30.             parent = cur;  
  31.             cur = cur->_left;  
  32.         }  
  33.         else if (cur->_key < key)  
  34.         {  
  35.             parent = cur;  
  36.             cur = cur->_right;  
  37.         }  
  38.         else  
  39.         {  
  40.             //要删除节点的左子树为空,分3种情况  
  41.             if (cur->_left == NULL)  
  42.             {  
  43.                 //注意判断父节点是否为空,若为空,则要删除的节点为根节点,如:只有根节点5和其右节点9  
  44.                 if (parent == NULL)  
  45.                 {  
  46.                     _root = cur->_right;  
  47.                     delete cur;  
  48.                     cur = NULL;  
  49.                     return true;  
  50.                 }  
  51.                 if (parent->_key > cur->_key)  
  52.                 {  
  53.                     del = cur;  
  54.                     parent->_left = cur->_right;  
  55.                     delete del;  
  56.                     return true;  
  57.                 }  
  58.                 else if (parent->_key < key)  
  59.                 {  
  60.                     del = cur;  
  61.                     parent->_right = cur->_right;  
  62.                     delete del;  
  63.                     return true;  
  64.                 }  
  65.             }  
  66.             //要删除节点的右子树为空,同样分3种情况  
  67.             else if (cur->_right == NULL)  
  68.             {  
  69.                 //注意判断父节点是否为空,若为空,则要删除的节点为根节点,如:只有根节点5和其左节点3  
  70.                 if (parent == NULL)  
  71.                 {  
  72.                     _root = cur->_left;  
  73.                     delete cur;  
  74.                     cur = NULL;  
  75.                     return true;  
  76.                 }  
  77.                 if (parent->_key > cur->_key)  
  78.                 {  
  79.                     del = cur;  
  80.                     parent->_left = cur->_left;  
  81.                     delete del;  
  82.                     return true;  
  83.                 }  
  84.                 else if (parent->_key < cur->_key)  
  85.                 {  
  86.                     del = cur;  
  87.                     parent->_right = cur->_left;  
  88.                     delete del;  
  89.                     return true;  
  90.                 }  
  91.             }  
  92.             //左右子树都不为空  
  93.             else  
  94.             {  
  95.                 Node* del = cur;  
  96.                 Node* parent = NULL;  
  97.                 Node* RightFirst = cur->_right;  
  98.                 //右边第一个节点的左子树为空  
  99.                 if (RightFirst->_left == NULL)  
  100.                 {  
  101.                     swap(RightFirst->_key, cur->_key);  
  102.                     swap(RightFirst->_value, cur->_value);  
  103.                     del = RightFirst;  
  104.                     cur->_right = RightFirst->_right;  
  105.                     delete del;  
  106.                     return true;  
  107.                 }  
  108.                 //右边第一个节点的左子树不为空  
  109.                 while (RightFirst->_left)  
  110.                 {  
  111.                     parent = RightFirst;  
  112.                     RightFirst = RightFirst->_left;  
  113.                 }  
  114.                    swap(RightFirst->_key, cur->_key);  
  115.                    swap(RightFirst->_value, cur->_value);  
  116.                    del = RightFirst;  
  117.                    parent->_left = RightFirst->_right;  
  118.                    delete del;  
  119.                    return true;  
  120.             }  
  121.         }  
  122.     }  
  123.     return false;  
  124. }  


删除递归法:

[cpp]  view plain  copy
  1.               bool _Remove_R(Node*& root, const K& key)  
  2. {  
  3.     //没有节点  
  4.     if (root == NULL)  
  5.     {  
  6.         return false;  
  7.     }  
  8.     //只有一个节点  
  9.     if (root->_left == NULL&&root->_right == NULL)  
  10.     {  
  11.         if (root->_key == key)  
  12.         {  
  13.             delete root;  
  14.             root = NULL;  
  15.             return true;  
  16.         }  
  17.         else  
  18.         {  
  19.             return false;  
  20.         }  
  21.   
  22.     }  
  23.   
  24.     //删除二叉搜索树节点的递归写法  
  25.     if (root->_key > key)  
  26.     {  
  27.         _Remove_R(root->_left, key);  
  28.     }  
  29.     else if (root->_key < key)  
  30.     {  
  31.         _Remove_R(root->_right, key);  
  32.     }  
  33.     else  
  34.     {  
  35.         Node* del = NULL;  
  36.           
  37.         if (root->_left == NULL)  
  38.         {  
  39.             del = root;  
  40.             root = root->_right;  
  41.             delete del;  
  42.             del = NULL;  
  43.             return true;  
  44.         }  
  45.         else if (root->_right == NULL)  
  46.         {  
  47.             del = root;  
  48.             root = root->_left;  
  49.             delete del;  
  50.             del = NULL;  
  51.             return true;  
  52.         }  
  53.         else  
  54.         {  
  55.             Node* RightFirst = root->_right;  
  56.   
  57.             while (RightFirst->_left)  
  58.             {  
  59.                 RightFirst = RightFirst->_left;  
  60.             }  
  61.   
  62.             swap(root->_key, RightFirst->_key);  
  63.             swap(root->_value, RightFirst->_value);  
  64.   
  65.             _Remove_R(root->_right, key);  
  66.             return true;  
  67.         }  
  68.     }  
  69. }  


插入非递归:

[cpp]  view plain  copy
  1.        //在二叉搜索树中插入节点  
  2. bool Insert(const K& key, const V& value)  
  3. {  
  4.     if (_root == NULL)  
  5.     {  
  6.         _root = new Node(key, value);  
  7.     }  
  8.   
  9.     Node* cur=_root;  
  10.     Node* parent = NULL;  
  11.     //首先找到要插入的位置  
  12.     while (cur)  
  13.     {  
  14.         if (cur->_key > key)  
  15.         {  
  16.             parent = cur;  
  17.             cur = cur->_left;  
  18.         }  
  19.         else if(cur->_key<key)  
  20.         {  
  21.             parent = cur;  
  22.             cur = cur->_right;  
  23.         }  
  24.         else  
  25.         {  
  26.             return false;  
  27.         }  
  28.     }  
  29.     //在找到插入位置以后,判断插入父亲节点的左边还是右边  
  30.     if (parent->_key > key)  
  31.     {  
  32.         parent->_left = new Node(key, value);  
  33.     }  
  34.     else  
  35.     {  
  36.         parent->_right = new Node(key, value);  
  37.     }  
  38.   
  39.     return true;  
  40. }  


 

插入递归:

[cpp]  view plain  copy
  1.               //递归插入法  
  2. bool _Insert_R(Node*& root, const K& key, const V& value)  
  3. {  
  4.     if (root == NULL)  
  5.     {  
  6.         root = new Node(key, value);  
  7.         return true;  
  8.     }  
  9.     if (root->_key > key)  
  10.     {  
  11.         return _Insert_R(root->_left, key, value);  
  12.     }  
  13.     else if(root->_key < key)  
  14.     {  
  15.         return _Insert_R(root->_right, key, value);  
  16.     }  
  17.     else  
  18.     {  
  19.         return false;  
  20.     }  
  21. }  


当二叉搜索树出现如下图情形时,效率最低:



完整代码及测试实现如下:

[cpp]  view plain  copy
  1. #include<iostream>  
  2. using namespace std;  
  3.   
  4. //二叉搜索树结构  
  5. template<class K, class V>  
  6. struct BSTreeNode  
  7. {  
  8.     BSTreeNode* _left;  
  9.     BSTreeNode* _right;  
  10.     K _key;  
  11.     V _value;  
  12.   
  13.     BSTreeNode(const K& key, const V& value)  
  14.         :_left(NULL)  
  15.         ,_right(NULL)  
  16.         ,_key(key)  
  17.         ,_value(value)  
  18.     {}  
  19.   
  20. };  
  21.   
  22. template<class K,class V>  
  23. class BSTree  
  24. {  
  25.     typedef BSTreeNode<K, V> Node;  
  26. public:  
  27.     BSTree()  
  28.         :_root(NULL)  
  29.     {}  
  30.       
  31.     //在二叉搜索树中插入节点  
  32.     bool Insert(const K& key, const V& value)  
  33.     {  
  34.         if (_root == NULL)  
  35.         {  
  36.             _root = new Node(key, value);  
  37.         }  
  38.   
  39.         Node* cur=_root;  
  40.         Node* parent = NULL;  
  41.         //首先找到要插入的位置  
  42.         while (cur)  
  43.         {  
  44.             if (cur->_key > key)  
  45.             {  
  46.                 parent = cur;  
  47.                 cur = cur->_left;  
  48.             }  
  49.             else if(cur->_key<key)  
  50.             {  
  51.                 parent = cur;  
  52.                 cur = cur->_right;  
  53.             }  
  54.             else  
  55.             {  
  56.                 return false;  
  57.             }  
  58.         }  
  59.         //在找到插入位置以后,判断插入父亲节点的左边还是右边  
  60.         if (parent->_key > key)  
  61.         {  
  62.             parent->_left = new Node(key, value);  
  63.         }  
  64.         else  
  65.         {  
  66.             parent->_right = new Node(key, value);  
  67.         }  
  68.   
  69.         return true;  
  70.     }  
  71.   
  72.   
  73.     //在二叉搜索树中查找节点  
  74.     Node* Find(const K& key)  
  75.     {  
  76.         Node* cur=_root;  
  77.         //开始遍历查找  
  78.         while (cur)  
  79.         {  
  80.             if (cur->_key > key)  
  81.             {  
  82.                 cur = cur->_left;  
  83.             }  
  84.             else if(cur->_key<key)  
  85.             {  
  86.                 cur = cur->_right;  
  87.             }  
  88.             else  
  89.             {  
  90.                 return cur;  
  91.             }  
  92.         }  
  93.            
  94.         return NULL;  
  95.     }  
  96.   
  97.   
  98.     //在二叉搜索树中删除节点  
  99.     bool Remove(const K& key)  
  100.     {  
  101.         //没有节点  
  102.         if (_root == NULL)  
  103.         {  
  104.             return false;  
  105.         }  
  106.         //只有一个节点  
  107.         if (_root->_left == NULL&&_root->_right == NULL)  
  108.         {  
  109.             if (_root->_key == key)  
  110.             {  
  111.                 delete _root;  
  112.                 _root = NULL;  
  113.                 return true;  
  114.             }  
  115.   
  116.             return false;  
  117.         }  
  118.   
  119.         Node* parent = NULL;  
  120.         Node* cur = _root;  
  121.         //遍历查找要删除节点的位置  
  122.         while (cur)  
  123.         {  
  124.             Node* del = NULL;  
  125.             if (cur->_key > key)  
  126.             {  
  127.                 parent = cur;  
  128.                 cur = cur->_left;  
  129.             }  
  130.             else if (cur->_key < key)  
  131.             {  
  132.                 parent = cur;  
  133.                 cur = cur->_right;  
  134.             }  
  135.             else  
  136.             {  
  137.                 //要删除节点的左子树为空,分3种情况  
  138.                 if (cur->_left == NULL)  
  139.                 {  
  140.                     //注意判断父节点是否为空,若为空,则要删除的节点为根节点,如:只有根节点5和其右节点9  
  141.                     if (parent == NULL)  
  142.                     {  
  143.                         _root = cur->_right;  
  144.                         delete cur;  
  145.                         cur = NULL;  
  146.                         return true;  
  147.                     }  
  148.                     if (parent->_key > cur->_key)  
  149.                     {  
  150.                         del = cur;  
  151.                         parent->_left = cur->_right;  
  152.                         delete del;  
  153.                         return true;  
  154.                     }  
  155.                     else if (parent->_key < key)  
  156.                     {  
  157.                         del = cur;  
  158.                         parent->_right = cur->_right;  
  159.                         delete del;  
  160.                         return true;  
  161.                     }  
  162.                 }  
  163.                 //要删除节点的右子树为空,同样分3种情况  
  164.                 else if (cur->_right == NULL)  
  165.                 {  
  166.                     //注意判断父节点是否为空,若为空,则要删除的节点为根节点,如:只有根节点5和其左节点3  
  167.                     if (parent == NULL)  
  168.                     {  
  169.                         _root = cur->_left;  
  170.                         delete cur;  
  171.                         cur = NULL;  
  172.                         return true;  
  173.                     }  
  174.                     if (parent->_key > cur->_key)  
  175.                     {  
  176.                         del = cur;  
  177.                         parent->_left = cur->_left;  
  178.                         delete del;  
  179.                         return true;  
  180.                     }  
  181.                     else if (parent->_key < cur->_key)  
  182.                     {  
  183.                         del = cur;  
  184.                         parent->_right = cur->_left;  
  185.                         delete del;  
  186.                         return true;  
  187.                     }  
  188.                 }  
  189.                 //左右子树都不为空  
  190.                 else  
  191.                 {  
  192.                     Node* del = cur;  
  193.                     Node* parent = NULL;  
  194.                     Node* RightFirst = cur->_right;  
  195.                     //右边第一个节点的左子树为空  
  196.                     if (RightFirst->_left == NULL)  
  197.                     {  
  198.                         swap(RightFirst->_key, cur->_key);  
  199.                         swap(RightFirst->_value, cur->_value);  
  200.                         del = RightFirst;  
  201.                         cur->_right = RightFirst->_right;  
  202.                         delete del;  
  203.                         return true;  
  204.                     }  
  205.                     //右边第一个节点的左子树不为空  
  206.                     while (RightFirst->_left)  
  207.                     {  
  208.                         parent = RightFirst;  
  209.                         RightFirst = RightFirst->_left;  
  210.                     }  
  211.                        swap(RightFirst->_key, cur->_key);  
  212.                        swap(RightFirst->_value, cur->_value);  
  213.                        del = RightFirst;  
  214.                        parent->_left = RightFirst->_right;  
  215.                        delete del;  
  216.                        return true;  
  217.                 }  
  218.             }  
  219.         }  
  220.         return false;  
  221.     }  
  222.   
  223.     bool Insert_R(const K& key, const V& value)  
  224.     {  
  225.         return _Insert_R(_root, key, value);  
  226.     }  
  227.   
  228.     Node* Find_R(const K& key)  
  229.     {  
  230.         return _Find_R(_root, key);  
  231.     }  
  232.   
  233.     bool Remove_R(const K& key)  
  234.     {  
  235.         return _Remove_R(_root, key);  
  236.     }  
  237.   
  238.     void InOrder()  
  239.     {  
  240.         _InOrder(_root);  
  241.         cout << endl;  
  242.     }  
  243.   
  244. protected:  
  245.           
  246.         bool _Remove_R(Node*& root, const K& key)  
  247.         {  
  248.             //没有节点  
  249.             if (root == NULL)  
  250.             {  
  251.                 return false;  
  252.             }  
  253.             //只有一个节点  
  254.             if (root->_left == NULL&&root->_right == NULL)  
  255.             {  
  256.                 if (root->_key == key)  
  257.                 {  
  258.                     delete root;  
  259.                     root = NULL;  
  260.                     return true;  
  261.                 }  
  262.                 else  
  263.                 {  
  264.                     return false;  
  265.                 }  
  266.   
  267.             }  
  268.   
  269.             //删除二叉搜索树节点的递归写法  
  270.             if (root->_key > key)  
  271.             {  
  272.                 _Remove_R(root->_left, key);  
  273.             }  
  274.             else if (root->_key < key)  
  275.             {  
  276.                 _Remove_R(root->_right, key);  
  277.             }  
  278.             else  
  279.             {  
  280.                 Node* del = NULL;  
  281.                   
  282.                 if (root->_left == NULL)  
  283.                 {  
  284.                     del = root;  
  285.                     root = root->_right;  
  286.                     delete del;  
  287.                     del = NULL;  
  288.                     return true;  
  289.                 }  
  290.                 else if (root->_right == NULL)  
  291.                 {  
  292.                     del = root;  
  293.                     root = root->_left;  
  294.                     delete del;  
  295.                     del = NULL;  
  296.                     return true;  
  297.                 }  
  298.                 else  
  299.                 {  
  300.                     Node* RightFirst = root->_right;  
  301.   
  302.                     while (RightFirst->_left)  
  303.                     {  
  304.                         RightFirst = RightFirst->_left;  
  305.                     }  
  306.   
  307.                     swap(root->_key, RightFirst->_key);  
  308.                     swap(root->_value, RightFirst->_value);  
  309.   
  310.                     _Remove_R(root->_right, key);  
  311.                     return true;  
  312.                 }  
  313.             }  
  314.         }  
  315.   
  316.         //递归查找法  
  317.         Node* _Find_R(Node* root, const K& key)  
  318.         {  
  319.             if (root == NULL)  
  320.             {  
  321.                 return NULL;  
  322.             }  
  323.             if (root->_key > key)  
  324.             {  
  325.                 return _Find_R(root->_left, key);  
  326.             }  
  327.             else if (root->_key < key)  
  328.             {  
  329.                 return _Find_R(root->_right, key);  
  330.             }  
  331.             else  
  332.             {  
  333.                 return root;  
  334.             }  
  335.         }  
  336.               
  337.         //递归插入法  
  338.         bool _Insert_R(Node*& root, const K& key, const V& value)  
  339.         {  
  340.             if (root == NULL)  
  341.             {  
  342.                 root = new Node(key, value);  
  343.                 return true;  
  344.             }  
  345.             if (root->_key > key)  
  346.             {  
  347.                 return _Insert_R(root->_left, key, value);  
  348.             }  
  349.             else if(root->_key < key)  
  350.             {  
  351.                 return _Insert_R(root->_right, key, value);  
  352.             }  
  353.             else  
  354.             {  
  355.                 return false;  
  356.             }  
  357.         }  
  358.   
  359.         void _InOrder(Node* root)  
  360.         {  
  361.             if (root == NULL)  
  362.             {  
  363.                 return;  
  364.             }  
  365.   
  366.             _InOrder(root->_left);  
  367.             cout << root->_key << " ";  
  368.             _InOrder(root->_right);  
  369.         }  
  370. protected:  
  371.     Node* _root;  
  372.   
  373. };  
  374.   
  375.   
  376. void Test()  
  377. {  
  378.     BSTree<intint> s;  
  379.       
  380.     //测试插入  
  381.     s.Insert_R(5, 1);  
  382.     s.Insert_R(4, 1);  
  383.     s.Insert_R(3, 1);  
  384.     s.Insert_R(6, 1);  
  385.     s.Insert_R(1, 1);  
  386.     s.Insert_R(2, 1);  
  387.     s.Insert_R(0, 1);  
  388.     s.Insert_R(9, 1);  
  389.     s.Insert_R(8, 1);  
  390.     s.Insert_R(7, 1);  
  391.   
  392.     //二叉搜索树按中序输出是有序的  
  393.     s.InOrder();  
  394.   
  395.     //测试查找  
  396.     cout << s.Find_R(6)->_key << endl;  
  397.   
  398.     //测试删除  
  399.     s.Remove(4);  
  400.     s.Remove(6);  
  401.     s.Remove(3);  
  402.     s.Remove(1);  
  403.     s.Remove(2);  
  404.       
  405.     //再次打印删除后的结果  
  406.     s.InOrder();  
  407.   
  408. }  
  409.   
  410. int main()  
  411. {  
  412.     Test();  
  413.     system("pause");  
  414.     return 0;  
  415. }  

运行结果:

0 1 2 3 4 5 6 7 8 9
6
0 5 7 8 9

请按任意键继续. . .



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值