二叉搜索树

二叉搜索树又称二叉查找树,它是一颗空树或者是具有以下特征的树:
1、若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值;
2、若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
3、它的左、右子树也分别为二叉搜索树。

二叉搜索树有查找,插入,删除等操作;有递归和非递归两种实现方法。

查找一个节点:树为空则返回空;若要查找的节点等于根节点,返回根节点;若要查找的节点大于根节点,递归查找右子树,反之递归查找左子树。

BSTreeNode<K, V>* _Find(BSTreeNode<K, V>* root, const K& key)
    {
        if (NULL == root)
        {
            return false;
        }
        if (key > root->_key)
        {
            _Find(root->_right, key);
        }
        else if (key < root->_key)
        {
            _Find(root->_left, key);
        }
        else
        {
            return root;
        }
    }

插入一个节点:如果树为空,新建一个节点做为根节点;若要插入的节点等于根节点,返回false;若要插入的节点大于根节点,递归插入右子树,反之递归插入左子树。

bool _Insert(BSTreeNode<K, V>* root, const K& key, const V& value)
    {
        if (root != NULL)
        {
            if (key > root->_key)
            {
                _Insert(root->_right, key, value);
                if (root->_right==NULL)
                {
                    root->_right = new BSTreeNode<K, V>(key, value);
                    return true;
                }
            }
            else if (key < root->_key)
            {
                _Insert(root->_left, key, value);
                if (root->_left==NULL)
                {   
                    root->_left = new BSTreeNode<K, V>(key, value);
                    return true;
                }
            }
            else if (key == root->_key)
            {
                return false;
            }
        }
    }

删除一个节点:分三种情况
(1)待删除节点没有孩子:
直接删除
这里写图片描述
(2)待删除节点只有一个孩子:
若cur的左孩子为空,让cur的parent指向cur的右孩子;
若cur的右孩子为空,让cur的parent指向cur的左孩子。
(情况1和情况2可以归为一类)
这里写图片描述
(3)待删除节点有两个孩子:
第一步:先找到cur右孩子的最左节点(保证了比cur左子树所有节点都大,比右子树其他节点都小)
第二步:交换最左节点和cur的值(在第一步的基础上,交换后还是二叉搜索树)
第三步:删除最左节点(问题转化成了前两种情况)
这里写图片描述
这里写图片描述
这里写图片描述

完整代码:

#include<iostream>
#include<cassert>
using namespace std;

template<class K, class V>
struct BSTreeNode
{
    K _key;
    V _value;
    BSTreeNode<K, V>* _left;
    BSTreeNode<K, V>* _right;

    BSTreeNode(const K& key, const V& value)
        :_key(key)
        , _value(value)
        , _left(NULL)
        , _right(NULL)
    {}
};

template<class K, class V>
class BSTree
{
public:
    BSTree()
        :_root(NULL)
    {}
    //非递归
    bool Insert_NR(const K& key, const V& value)
    {
        if (NULL == _root)
        {
            _root = new BSTreeNode<K, V>(key, value);
        }
        else
        {
            BSTreeNode<K, V>* cur = _root;
            BSTreeNode<K, V>* parent = NULL;
            while (cur)
            {
                if (key > cur->_key)
                {
                    parent = cur;
                    cur = cur->_right;
                }
                else if (key < cur->_key)
                {
                    parent = cur;
                    cur = cur->_left;
                }
                else
                {
                    return false;
                }
            }
            if (key < parent->_key)
            {
                parent->_left = new BSTreeNode<K, V>(key, value);
            }
            else
            {
                parent->_right = new BSTreeNode<K, V>(key, value);
            }
        }
        return true;
    }
    bool Insert_R(const K& key, const V& value)
    {
        if (NULL == _root)
        {
            _root = new BSTreeNode<K, V>(key, value);
            return true;
        }
        _Insert(_root, key, value);
    }

    bool Remove_NR(const K& key)
    {
        if (NULL == _root)
        {
            return false;
        }
        BSTreeNode<K, V>* del = _root;
        BSTreeNode<K, V>* parent = NULL;
        while (del)
        {
            if (key > del->_key)
            {
                parent = del;
                del = del->_right;
            }
            else if (key < del->_key)
            {
                parent = del;
                del = del->_left;
            }
            else
            {
                break;
            }
        }
        if (del)
        {
            //最多一个孩子
            if (del->_left == NULL)
            {

                if (del == _root)
                {
                    _root = del->_right;
                }
                else
                {
                    if (del == parent->_left)
                    {
                        parent->_left = del->_right;
                    }
                    else
                    {
                        parent->_right = del->_right;
                    }
                }
                delete del;
                del = NULL;
                return true;
            }
            else if (del->_right == NULL)
            {
                if (del == _root)
                {
                    _root = del->_left;
                }
                else
                {
                    if (del == parent->_left)
                    {
                        parent->_left = del->_left;
                    }
                    else
                    {
                        parent->_right = del->_left;
                    }
                }
                delete del;
                del = NULL;
                return true;
            }

            //两个孩子
            else
            {
                //找右子树的最左节点
                parent = del;
                BSTreeNode<K, V>* leftmost = del->_right;
                while (leftmost->_left)
                {
                    parent = leftmost;
                    leftmost = leftmost->_left;
                }
                //交换
                swap(del->_key, leftmost->_key);
                swap(del->_value, leftmost->_value);

                if (leftmost == parent->_left)
                {
                    parent->_left = leftmost->_right;
                }
                if (leftmost == parent->_right)
                {
                    parent->_right = leftmost->_right;
                }
                delete leftmost;
                leftmost = NULL;
                return true;
            }
        }
        return false;
    }
    bool Remove_R(const K& key)
    {
        return _Remove(_root, key);
    }

    BSTreeNode<K, V>* Find_NR(const K& key)
    {
        while (_root)
        {
            if (key > _root->_key)
            {
                _root = _root->_right;
            }
            else if (key < _root->_key)
            {
                _root = _root->_left;
            }
            else
            {
                return _root;
            }
        }
        return NULL;
    }
    BSTreeNode<K, V>* Find_R(const K& key)
    {
        return _Find(_root, key);
    }
    void InOrder()
    {
        _InOrder(_root);
    }
protected:
    bool _Insert(BSTreeNode<K, V>* root, const K& key, const V& value)
    {
        if (root != NULL)
        {
            if (key > root->_key)
            {
                _Insert(root->_right, key, value);
                if (root->_right==NULL)
                {
                    root->_right = new BSTreeNode<K, V>(key, value);
                    return true;
                }
            }
            else if (key < root->_key)
            {
                _Insert(root->_left, key, value);
                if (root->_left==NULL)
                {   
                    root->_left = new BSTreeNode<K, V>(key, value);
                    return true;
                }
            }
            else if (key == root->_key)
            {
                return false;
            }
        }
    }
    bool _Remove(BSTreeNode<K, V>*& root, const K& key)
    {
        if (NULL == root)
        {
            return false;
        }
        if (key > root->_key)
        {
            return _Remove(root->_right, key);
        }
        else if (key < root->_key)
        {
            return _Remove(root->_left, key);
        }
        else
        {
            BSTreeNode<K, V>* del = root;
            if (root->_left == NULL)
            {
                root = root->_right; //root是引用
                delete del;
            }
            else if (root->_right == NULL)
            {
                root = root->_left;
                delete del;
            }
            else
            {
                BSTreeNode<K, V>* leftmost = root->_right;
                while (leftmost->_left)
                {
                    leftmost = leftmost->_left;
                }
                swap(del->_key, leftmost->_key);
                swap(del->_value, leftmost->_value);

                return _Remove(root->_right, key);
            }
        } 
    }
    BSTreeNode<K, V>* _Find(BSTreeNode<K, V>* root, const K& key)
    {
        if (NULL == root)
        {
            return false;
        }
        if (key > root->_key)
        {
            _Find(root->_right, key);
        }
        else if (key < root->_key)
        {
            _Find(root->_left, key);
        }
        else
        {
            return root;
        }
    }
    void _InOrder(BSTreeNode<K, V>* root)
    {
        if (NULL == root)
        {
            return;
        }
        _InOrder(root->_left);
        cout << root->_key << "->" << root->_value << endl;
        _InOrder(root->_right);
    }
protected:
    BSTreeNode<K, V>* _root;
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值