BSTree ---- 二叉搜索树

BSTree ---- 二叉搜索树

二叉搜索树的性质:
  1.  每个结点都有一个作为搜索依据的关键码(key),所有结点的关键码互不相同。
  2.  左子树上所有结点的关键码(key)都小于根结点的关键码(key)。
  3.  右子树上所有结点的关键码(key)都大于根结点的关键码(key)。
  4.  左右子树都是二叉搜索树。
故中序遍历这棵树它的key是按 升序排列

  • 二叉搜索树的插入

插入结点时,比当前结点小就往左树走,比当前结点大,就往右树走,直到为空就可以插入。


  • 二叉搜索树的查找
查找与插入类似,查找的这个结点比当前结点小,就往左走,比当前结点大,就往右走,与当前结点相同就代表找到了,如果左右都为空则代表没找到。

  • 二叉搜索树的删除
删除要分为3种情况
左为空
  1. 删除的为根结点的话,直接让根为根的右孩子。
  2. 若parent的左为cur,则parent的左孩子为cur的左孩子,若parent的右为cur,则parent的右孩子cur的右孩子。



右为空
  1. 删除的为根结点的话,直接让根为根的左孩子。
  2. 若parent的左为cur,则parent的左孩子为cur的左孩子,若parent的右为cur,则parent的右孩子cur的右孩子。



左右都不为空
这时我们用 替换法删除
左子树的最右结点或者右子树的最左结点,替换删除即可。(以替换最右子树的最左结点为例)
情况一:

情况二:


扫描二维码关注公众号,回复: 1014031 查看本文章

完整代码
template<class K>
struct BinarySearchTree
{
          BinarySearchTree* _left;
          BinarySearchTree* _right;
          K _key;

          BinarySearchTree(const K& key)
                   :_left(NULL)
                   , _right(NULL)
                   , _key(key)
             {}
};

template<class K>
class BSTree
{
          typedef BinarySearchTree<K> Node;
public:

          BSTree()
                   :_root(NULL)
          {}

          bool Insert(const K& key)//插入
          {
                   if (_root == NULL)
                   {
                             _root = new Node(key);
                   }
                   Node* cur = _root;
                   Node* parent = NULL;
                   while (cur)
                   {
                             if (cur->_key > key)
                             {
                                      parent = cur;
                                      cur = cur->_left;
                             }
                             else if (cur->_key < key)
                             {
                                      parent = cur;
                                      cur = cur->_right;
                             }
                             else
                             {
                                      return false;
                             }
                   }
                   cur = new Node(key);

                   if (parent->_key > key)
                   {
                             parent->_left = cur;
                   }
                   else
                   {
                             parent->_right = cur;
                   }
                   return true;
          }

          bool InsertR(const K& key)//递归插入
          {
                   return _InsertR(_root, key);
          }

          bool _InsertR(Node*& root,const K& key)
          {
                   if (root == NULL)
                   {
                             root = new Node(key);
                             return true;
                   }
                   if (root->_key > key)
                   {
                             return _InsertR(root->_left, key);
                   }
                   else if (root->_key < key)
                   {
                             return _InsertR(root->_right, key);
                   }
                   else
                   {
                             return false;
                   }
          }

          Node* Find(const K& key)
          {
                   if (_root == NULL)
                   {
                             return NULL;
                   }
                   Node* cur = _root;
                   while (cur)
                   {
                             if (cur->_key > key)
                             {
                                      cur = cur->_left;
                             }
                             else if (cur->_key < key)
                             {
                                      cur = cur->_right;
                             }
                             else
                             {
                                      return cur;
                             }
                   }
                   return NULL;
          }

          Node* FindR(const K& key)//递归查找
          {
                   return _FindR(_root, key);
          }

          Node* _FindR(Node* root, const K& key)
          {
                   if (root == NULL)
                   {
                             return NULL;
                   }
                   if (root->_key > key)
                   {
                             return _FindR(root->_left, key);
                   }
                   else if (root->_key < key)
                   {
                             return _FindR(root->_right, key);
                   }
                   else
                   {
                             return root;
                   }
          }

          bool Remove(const K& key)
          {
                   Node* parent = NULL;
                   Node* cur = _root;
                   while (cur)
                   {
                             if (cur->_key > key)
                             {
                                      parent = cur;
                                      cur = cur->_left;
                             }
                             else if (cur->_key < key)
                             {
                                      parent = cur;
                                      cur = cur->_right;
                             }
                             else
                             {
                                      //删除
                                      //1.左为空
                                      //2.右为空
                                      //3.左右都不为空
                                      Node* del = cur;
                                      if(cur->_left == NULL)       //左为空
                                      {
                                                if (parent == NULL) //若删除的为根节点,则单独处理
                                                {
                                                          _root = cur->_right;
                                                }
                                                else                                
                                                {
                                                          if (parent->_left == cur)
                                                          {
                                                                   parent->_left = cur->_right;
                                                          }
                                                          else
                                                          {
                                                                   parent->_right = cur->_right;
                                                          }
                                                }
                                      }
                                      else if (cur->_right == NULL)   //右为空
                                      {
                                                if (parent == NULL)   //若删除的为根节点,则单独处理
                                                {
                                                          _root = cur->_left;
                                                }
                                                else              
                                                {
                                                          if (parent->_left == cur)
                                                          {
                                                                   parent->_left = cur->_left;
                                                          }
                                                          else
                                                          {
                                                                   parent->_right = cur->_left;
                                                          }
                                                }
                                      }
                                      else          //左右都不为空
                                      {
                                                //替换法删除
                                                Node* parent = cur;
                                                Node* sub = cur->_right;
                                                while (sub->_left)//找最左结点
                                                {
                                                          parent = sub;
                                                          sub = sub->_left;
                                                }

                                                cur->_key = sub->_key;

                                                if (cur->_key == parent->_key)
                                                {
                                                          parent->_right = sub->_right;
                                                }
                                                else
                                                {
                                                          parent->_left = sub->_right;
                                                }
                                                delete sub;
                                      }
                                      return true;
                             }
                   }
                   return false;
          }

          bool RemoveR(const K& key)//递归删除
          {
                   return _RemoveR(_root, key);
          }

          bool _RemoveR(Node*& root, const K& key)
          {
                   if (root == NULL)
                   {
                             return false;
                   }
                   if (root->_key > key)
                   {
                             _RemoveR(root->_left, key);
                   }
                   else if (root->_key < key)
                   {
                             _RemoveR(root->_right, key);
                   }
                   else
                   {
                             Node* del = root;
                             if (root->_left == NULL)
                             {
                                      root = root->_right;
                             }
                             else if (root->_right == NULL)
                             {
                                      root = root->_left;
                             }
                             else
                             {
                                      Node* sub = root->_right;
                                      while (sub->_left)
                                      {
                                                sub = sub->_left;
                                      }
                                      swap(root->_key, sub->_key);
                                      _RemoveR(root->_right, key);
                             }
                             delete del;
                             del = NULL; 
                   }
                   return true;
          }

          void InOrder()
          {
                   _InOrder(_root);
                   cout << endl;
          }

          void _InOrder(Node* root)
          {
                   if (root == NULL)
                   {
                             return;
                   }
                   _InOrder(root->_left);
                   cout << root->_key << " ";
                   _InOrder(root->_right);
          }

protected:
          Node* _root;
};

//测试
void TestBSTree()
{
          int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
    BSTree<int> t;
          for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
          {
                   //t.Insert(a[i]);
                   t.InsertR(a[i]);
          }
          t.InOrder();
          
          //cout << t.Find(5) << endl;
          // 测试情况
          // 1. 左为空/右为空
          // 2. 左右都不为空
          t.Remove(8);
          t.Remove(2);
          t.Remove(1);
          t.Remove(5);

          t.InOrder();

          t.Remove(0);
          t.Remove(1);
          t.Remove(2);
          t.Remove(3);
          t.Remove(4);
          t.Remove(5);
          t.Remove(6);
          t.Remove(7);
          t.Remove(8);
          t.Remove(9);
          t.InOrder();

          //// 相不到情况
          /*t.RemoveR(0);
          t.RemoveR(1);
          t.RemoveR(2);
          t.RemoveR(3);
          t.RemoveR(4);
          t.RemoveR(5);
          t.RemoveR(6);
          t.RemoveR(7);
          t.RemoveR(9);

          t.InOrder();*/
}

猜你喜欢

转载自blog.csdn.net/ling_hun_pang_zi/article/details/79827108