二叉搜索树—增删查

性质
-每个节点的key值各不相同
-左子树上所有节点的key值小于根结点
-右子树上的所有节点key值大于根结点
-左右子树都是二叉搜索树

Insert插入

bool Insert(const K& key)//非递归插入
    {
        if (_root == NULL)
        {
            _root = new Node (key);
            return true;
        }
        Node* cur = _root;
        Node* parent = NULL;
        while (cur)
        {
            parent = cur;
            if (key > parent->_key)
            {
                cur = parent->_right;
            }
            else if (key < parent->_key)
            {
                cur = parent->_left;
            }
            else
            {
                return false;
            }
        }
        //cur找到NULL了,插入新节点
        if (key < parent->_key)
        {
            parent->_left = new Node(key);
        }
        else
        {
            parent->_right = new Node(key);
        }
        return true;
    }

Find查找

    bool Find(const K& key)//非递归查找
    {
        if (_root == NULL) //空树直接返回
        {
            return false;
        }
        //非空树
        Node* cur = _root:
        while (cur)
        {
            if (key > cur->_key) //key值大 往右子树找
            {
                cur = cur->_right;
            }
            else if (key < cur->_key) //反之 左子树
            {
                cur = cur->_left;
            }
            else  //找到了返回真
            {
                return true;
            }
        }
        return false; //遍历之后发现并不存在
    }

Remove删除


    bool Remove(const K& key)//非递归删除
    {
        if (_root == NULL)
        {
            return false;
        }
        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 //找到了  分三种情况
            {
                if (cur->_left == NULL)//根的左为空
                {
                    if (parent == NULL)
                    {
                        _root = cur->_right;
                        delete cur;
                        return true;
                    }
                    else
                    {
                        Node* tmp = cur->_right;
                        if (parent->_left == cur)
                        {
                            parent->_left = tmp;
                        }
                        else if (parent->_right == cur)
                        {
                            parent->_right = tmp;
                        }
                        delete cur;
                        return true;
                    }

                }
                else if(cur->_right == NULL)
                {
                    Node* tmp = cur->_left;
                    if (parent->_left == cur)
                    {
                        parent->_left = tmp;
                    }
                    else if (parent->_right == cur)
                    {
                        parent->_right = tmp;
                    }
                    delete cur;
                    return true;
                }
                else//cur左右两个孩子均不为空
                {
                    parent = cur;
                    Node* subleft = cur->_right;//找右孩子的最左节点
                    while (subleft->_left)
                    {
                        parent = subleft;
                        subleft = subleft->_left;
                    }
                    cur->_key = subleft->_key;

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

二叉搜索树的退化和缺陷
-如果插入的数接近有序或者基本有序时,会成为一条单向单一的树,类似于链表
例如:{0,1,2,3,4,5,6,7,8,9}

这个时候它的时间复杂度为O(N),所以要考虑高度

附上详细代码

#pragma once

template<class K>
struct BinarySearchTreeNode
{
    K _key;
    BinarySearchTreeNode<K>* _left;
    BinarySearchTreeNode<K>* _right;
    BinarySearchTreeNode(const K& key)
        :_key(key)
        ,_left(NULL)
        ,_right(NULL)
    {}
};

template<class K>
class BSTree
{
    typedef BinarySearchTreeNode<K> Node;
public:
    BSTree() //无参构造
        :_root(NULL)
    {}
    BSTree(K* a, size_t n) //构造函数
    {
        _root = NULL;
        for (size_t i = 0; i < n; ++i)
        {
            InsertR(a[i]);
        }
    }
    ~BSTree()
    {}
    bool Insert(const K& key)//非递归插入
    {
        if (_root == NULL)
        {
            _root = new Node (key);
            return true;
        }
        Node* cur = _root;
        Node* parent = NULL;
        while (cur)
        {
            parent = cur;
            if (key > parent->_key)
            {
                cur = parent->_right;
            }
            else if (key < parent->_key)
            {
                cur = parent->_left;
            }
            else
            {
                return false;
            }
        }
        //cur找到NULL了,插入新节点
        if (key < parent->_key)
        {
            parent->_left = new Node(key);
        }
        else
        {
            parent->_right = new Node(key);
        }
        return true;
    }
    bool Find(const K& key)//非递归查找
    {
        if (_root == NULL) //空树直接返回
        {
            return false;
        }
        //非空树
        Node* cur = _root:
        while (cur)
        {
            if (key > cur->_key) //key值大 往右子树找
            {
                cur = cur->_right;
            }
            else if (key < cur->_key) //反之 左子树
            {
                cur = cur->_left;
            }
            else  //找到了返回真
            {
                return true;
            }
        }
        return false; //遍历之后发现并不存在
    }
    bool Remove(const K& key)//非递归删除
    {
        if (_root == NULL)
        {
            return false;
        }
        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 //找到了  分三种情况
            {
                if (cur->_left == NULL)//根的左为空
                {
                    if (parent == NULL)
                    {
                        _root = cur->_right;
                        delete cur;
                        return true;
                    }
                    else
                    {
                        Node* tmp = cur->_right;
                        if (parent->_left == cur)
                        {
                            parent->_left = tmp;
                        }
                        else if (parent->_right == cur)
                        {
                            parent->_right = tmp;
                        }
                        delete cur;
                        return true;
                    }

                }
                else if(cur->_right == NULL)
                {
                    Node* tmp = cur->_left;
                    if (parent->_left == cur)
                    {
                        parent->_left = tmp;
                    }
                    else if (parent->_right == cur)
                    {
                        parent->_right = tmp;
                    }
                    delete cur;
                    return true;
                }
                else//cur左右两个孩子均不为空
                {
                    parent = cur;
                    Node* subleft = cur->_right;//找右孩子的最左节点
                    while (subleft->_left)
                    {
                        parent = subleft;
                        subleft = subleft->_left;
                    }
                    cur->_key = subleft->_key;

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

    //bool Insert(const K& key) //递归插入
    //{
    //  return _InsertR(_root, key);
    //}
//  bool RemoveR(const K& key) //递归删除
//  {
//      return _RemoveR(_root, key);
//  }
    void Inorder()
    {
        _Inorder(_root);
        cout << endl;
    }
protected:
     bool _InsertR(Node*& root,const K& key)
    {
        if (root == NULL)
        {
            root = new Node(key);
        }
        else
        {
            if (key > root->_key)
            {
                return _InsertR(root->_right, key);
            }
            else 
            {
                return _InsertR(root->_left, key);
            }
        }
        return true;
    }
     bool _RemoveR(Node*& root, const K& key)
    {
         if (root == NULL)
         {
             return false;
         }
         else if (root->_key > key)
         {
             return _RemoveR(root->_left, key);
         }
         else if (root->_key < key)
         {
             return _RemoveR(root->_right, key);
         }
         else //刚好根节点就是要删除的节点,分三种情况
         {
             if (root->_left == NULL)  //根节点左为空
             {
                 root = root->_right;
             }
             if (root->_right == NULL)  //根节点右为空
             {
                 root = root->_left;
             }
             else if //根节点左右都不为空,找替代节点
             {
                 Node* parent = root;
                 Node* subleft = root->right;  
                 while (subleft->_left)//右子树最左节点
                 {
                     root->key = subleft->key;
                     subleft = subleft->left;
                 }
             }
         }
    }

     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> t1;
    for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
    {
        t1.Insert(a[i]);
    }
    t1.Inorder();
    t1.Remove(1);   
    t1.Inorder();
    t1.Remove(0);
    t1.Inorder();
    t1.Remove(9);
    t1.Inorder();
    t1.Remove(5);
    t1.Inorder();
    t1.Remove(2);
    t1.Inorder();
    t1.Remove(3);
    t1.Inorder();
    t1.Remove(4);
    t1.Inorder();
    t1.Remove(6);   
    t1.Inorder();
    t1.Remove(7);
    t1.Inorder();
    t1.Remove(8);
    t1.Inorder();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值