0
点赞
收藏
分享

微信扫一扫

2022-02-12 二叉搜索树的C++实现

眼君 2022-02-12 阅读 26

二叉搜索树是经典的数据结构,对于随机无序的大规模数据查询,可以做到O(logN)的插入及查询,实现没有想象的那么容易,当然也没有太复杂。

以下是基于递归实现。

#ifndef BSTREE
#define BSTREE

#include <cassert>
#include <vector>

namespace ST
{
    template <typename K, typename V>
    struct BST; //声明二叉树

    template <typename K, typename V>
    struct BNode //链表节点
    {
        BNode(const K &keys, const V &vals, int Num)
            : key(keys), val(vals), N(Num) {}

    private:
        K key;
        V val;
        BNode *left = nullptr;
        BNode *right = nullptr;
        int N = 0;
        friend BST<K, V>; //设置二叉树为友元
    };

    template <typename K, typename V>
    struct BST //定义二叉树
    {
        BST() = default; //默认构造

        BST(const BST &rhs) //拷贝构造
        : root(new BNode<K, V>(rhs.root->key, rhs.root->val, rhs.root->N))
        {
            copy(rhs.root, root);
        }

        BST &operator=(const BST &rhs) //拷贝赋值
        {
            if (root == rhs.root)
            {
                return *this;
            }
            if (root)
            {
                debuild(root);
                root = nullptr;
            }
            if (rhs.root)
            {
                root = new BNode<K, V>(rhs.root->key, rhs.root->val, rhs.root->N);
                copy(rhs.root, root);
            }
            return *this;
        }

        ~BST() //析构
        {
            debuild(root);
        }

        int size(); //返回元素个数

        std::pair<bool, V> get(const K &keys); //返回是否含有键,及键对应的值

        bool contains(const K &keys); //是否包含值

        void put(const K &keys, const V &vals); //插入键值对

        K max(); //最大键

        K min(); //最小键

        std::pair<bool, K> floor(const K &keys); //小于等于keys的最大键

        std::pair<bool, K> ceiling(const K &keys); //大于等于keys的最小键

        std::pair<bool, K> select(int k); //返回排名第k个键

        int rank(const K &keys); // keys的排名

        void del(const K &keys); //删除keys键值对

        void delMin(); //删除最小值

        void delMax(); //删除最大值

        std::vector<K> keyVec(); //返回排序后的所有键

        std::vector<K> keyVec(const K &keysLo, const K &keysHi); //返回[keysLo, keysHi]之间的键

    private:
        void debuild(BNode<K, V> *x); //递归删除节点

        void copy(BNode<K, V> *oriT, BNode<K, V> *newT); //递归拷贝节点

        int size(BNode<K, V> *x);

        std::pair<bool, V> get(BNode<K, V> *x, const K &keys);

        bool contains(BNode<K, V> *x, const K &keys);

        BNode<K, V> *put(BNode<K, V> *x, const K &keys, const V &vals);

        BNode<K, V> *min(BNode<K, V> *x);

        BNode<K, V> *max(BNode<K, V> *x);

        BNode<K, V> *floor(BNode<K, V> *x, const K &key);

        BNode<K, V> *ceiling(BNode<K, V> *x, const K &key);

        BNode<K, V> *select(BNode<K, V> *x, int k);

        int rank(BNode<K, V> *x, const K &keys);

        BNode<K, V> *del(BNode<K, V> *x, const K &keys);

        BNode<K, V> *delMin(BNode<K, V> *x);

        BNode<K, V> *divMin(BNode<K, V> *x); //分离最小值节点,不delete

        BNode<K, V> *delMax(BNode<K, V> *x);

        BNode<K, V> *divMax(BNode<K, V> *x); //分离最大值节点,不delete

        void keyVec(BNode<K, V> *x, std::vector<K> &queue, const K &keysLo, const K &keysHi);

        BNode<K, V> *root = nullptr; //二叉树根节点
    };

    template <typename K, typename V>
    void ST::BST<K, V>::debuild(BNode<K, V> *x)
    {
        if (x == nullptr)
        {
            return;
        }
        BNode<K, V> *tempL = x->left;
        BNode<K, V> *tempR = x->right;
        delete x;
        debuild(tempL);
        debuild(tempR);
    }

    template <typename K, typename V>
    void ST::BST<K, V>::copy(BNode<K, V> *oriT, BNode<K, V> *newT)
    {
        if (oriT)
        {
            if (oriT->left)
            {
                newT->left = new BNode<K, V>(oriT->left->key, oriT->left->val, oriT->left->N);
            }
            if (oriT->right)
            {
                newT->right = new BNode<K, V>(oriT->right->key, oriT->right->val, oriT->right->N);
            }
            copy(oriT->left, newT->left);
            copy(oriT->right, newT->right);
        }
        else
        {
            return;
        }
    }

    template <typename K, typename V>
    int ST::BST<K, V>::size()
    {
        return size(root);
    }

    template <typename K, typename V>
    int ST::BST<K, V>::size(BNode<K, V> *x)
    {
        if (x == nullptr)
        {
            return 0;
        }
        else
        {
            return x->N;
        }
    }

    template <typename K, typename V>
    std::pair<bool, V> ST::BST<K, V>::get(const K &keys)
    {
        return get(root, keys);
    }

    template <typename K, typename V>
    std::pair<bool, V> ST::BST<K, V>::get(BNode<K, V> *x, const K &keys)
    {
        if (x == nullptr)
        {
            return std::pair<bool, V>(false, V());
        }
        if (keys < x->key)
        {
            return get(x->left, keys);
        }
        else if (keys > x->key)
        {
            return get(x->right, keys);
        }
        else
        {
            return std::pair<bool, V>(true, x->val);
        }
    }

    template <typename K, typename V>
    bool ST::BST<K, V>::contains(const K &keys)
    {
        return contains(root, keys);
    }

    template <typename K, typename V>
    bool ST::BST<K, V>::contains(BNode<K, V> *x, const K &keys)
    {
        if (x == nullptr)
        {
            return false;
        }
        if (keys < x->key)
        {
            return contains(x->left, keys);
        }
        else if (keys > x->key)
        {
            return contains(x->right, keys);
        }
        else
        {
            return true;
        }
    }

    template <typename K, typename V>
    void ST::BST<K, V>::put(const K &keys, const V &vals)
    {
        root = put(root, keys, vals);
    }

    template <typename K, typename V>
    BNode<K, V> *ST::BST<K, V>::put(BNode<K, V> *x, const K &keys, const V &vals)
    {
        if (x == nullptr)
        {
            return new BNode<K, V>(keys, vals, 1);
        }
        if (keys < x->key)
        {
            x->left = put(x->left, keys, vals);
        }
        else if (keys > x->key)
        {
            x->right = put(x->right, keys, vals);
        }
        else
        {
            x->val = vals;
        }
        x->N = size(x->left) + size(x->right) + 1;
        return x;
    }

    template <typename K, typename V>
    K ST::BST<K, V>::min()
    {
        return min(root)->key;
    }

    template <typename K, typename V>
    BNode<K, V> *ST::BST<K, V>::min(BNode<K, V> *x)
    {
        if (x->left == nullptr)
        {
            return x;
        }
        return min(x->left);
    }

    template <typename K, typename V>
    K ST::BST<K, V>::max()
    {
        return max(root)->key;
    }

    template <typename K, typename V>
    BNode<K, V> *ST::BST<K, V>::max(BNode<K, V> *x)
    {
        if (x->right == nullptr)
        {
            return x;
        }
        return max(x->right);
    }

    template <typename K, typename V>
    std::pair<bool, K> ST::BST<K, V>::floor(const K &keys)
    {
        BNode<K, V> *x = floor(root, keys);
        if (x == nullptr)
        {
            return std::pair<bool, K>(false, K());
        }
        return std::pair<bool, K>(true, x.key);
    }

    template <typename K, typename V>
    BNode<K, V> *ST::BST<K, V>::floor(BNode<K, V> *x, const K &keys)
    {
        if (x == nullptr)
        {
            return nullptr;
        }
        else if (keys == x->key)
        {
            return x;
        }
        else if (keys < x->key)
        {
            return floor(x.left, keys);
        }
        else
        {
            BNode<K, V> *t = floor(x.right, keys);
            if (t != nullptr)
            {
                return t;
            }
            else
            {
                return x;
            }
        }
    }

    template <typename K, typename V>
    std::pair<bool, K> ST::BST<K, V>::ceiling(const K &keys)
    {
        BNode<K, V> *x = ceiling(root, keys);
        if (x == nullptr)
        {
            return std::pair<bool, K>(false, K());
        }
        return std::pair<bool, K>(true, x.key);
    }

    template <typename K, typename V>
    BNode<K, V> *ST::BST<K, V>::ceiling(BNode<K, V> *x, const K &keys)
    {
        if (x == nullptr)
        {
            return nullptr;
        }
        else if (keys == x->key)
        {
            return x;
        }
        else if (keys > x->key)
        {
            return ceiling(x->right, keys);
        }
        else
        {
            BNode<K, V> *t = ceiling(x->left, keys);
            if (t != nullptr)
            {
                return t;
            }
            else
            {
                return x;
            }
        }
    }

    template <typename K, typename V>
    std::pair<bool, K> ST::BST<K, V>::select(int k)
    {
        BNode<K, V> *x = select(root, k);
        if (x)
        {
            return std::pair<bool, K>(true, x.key);
        }
        else
        {
            return std::pair<bool, K>(true, K());
        }
    }

    template <typename K, typename V>
    BNode<K, V> *ST::BST<K, V>::select(BNode<K, V> *x, int k)
    {
        if (x == nullptr)
        {
            return nullptr;
        }
        int t = size(x->left);
        if (t > k)
        {
            return select(x->left, k);
        }
        else if (t < k)
        {
            return select(x->right, k - t - 1);
        }
        else
        {
            return x;
        }
    }

    template <typename K, typename V>
    int ST::BST<K, V>::rank(const K &keys)
    {
        return rank(root, keys);
    }

    template <typename K, typename V>
    int ST::BST<K, V>::rank(BNode<K, V> *x, const K &keys)
    {
        if (x == nullptr)
        {
            return 0;
        }
        if (keys < x->key)
        {
            return rank(x->left, keys);
        }
        else if (keys > x->key)
        {
            return 1 + size(x->left) + rank(x->right, keys);
        }
        else
        {
            return size(x->left);
        }
    }

    template <typename K, typename V>
    void ST::BST<K, V>::delMin()
    {
        root = delMin(root);
    }

    template <typename K, typename V>
    BNode<K, V> *ST::BST<K, V>::delMin(BNode<K, V> *x)
    {
        if (x->left == nullptr)
        {
            BNode<K, V> *temp = x->right;
            delete x;
            x = nullptr;
            return temp;
        }
        x->left = delMin(x->left);
        x->N = size(x->left) + size(x->right) + 1;
        return x;
    }

    template <typename K, typename V>
    BNode<K, V> *ST::BST<K, V>::divMin(BNode<K, V> *x)
    {
        if (x->left == nullptr)
        {
            BNode<K, V> *temp = x->right;
            return temp;
        }
        x->left = divMin(x->left);
        x->N = size(x->left) + size(x->right) + 1;
        return x;
    }

    template <typename K, typename V>
    void ST::BST<K, V>::delMax()
    {
        root = delMax(root);
    }

    template <typename K, typename V>
    BNode<K, V> *ST::BST<K, V>::delMax(BNode<K, V> *x)
    {
        if (x->right == nullptr)
        {
            BNode<K, V> *temp = x->left;
            delete x;
            x = nullptr;
            return temp;
        }
        x->right = delMax(x->right);
        x->N = size(x->left) + size(x->right) + 1;
        return x;
    }

    template <typename K, typename V>
    BNode<K, V> *ST::BST<K, V>::divMax(BNode<K, V> *x)
    {
        if (x->right == nullptr)
        {
            BNode<K, V> *temp = x->left;
            return temp;
        }
        x->right = divMax(x->right);
        x->N = size(x->left) + size(x->right) + 1;
        return x;
    }

    template <typename K, typename V>
    void ST::BST<K, V>::del(const K &keys)
    {
        root = del(root, keys);
    }

    template <typename K, typename V>
    BNode<K, V> *ST::BST<K, V>::del(BNode<K, V> *x, const K &keys)
    {
        if (x == nullptr)
        {
            return nullptr;
        }
        if (keys < x->key)
        {
            x->left = del(x->left, keys);
        }
        else if (keys > x->key)
        {
            x->right = del(x->right, keys);
        }
        else
        {
            if (x->right == nullptr)
            {
                BNode<K, V> *temp = x->left;
                delete x;
                return temp;
            }
            else if (x->left = nullptr)
            {
                BNode<K, V> *temp = x->right;
                delete x;
                return temp;
            }
            BNode<K, V> *temp = x;
            if (temp->left->N > temp->right->N)
            {
                x = max(temp->left);
                x->left = divMax(temp->left);
                x->right = temp->right;
                delete temp;
                temp = nullptr;
            }
            else
            {
                x = min(temp->right);
                x->right = divMin(temp->right);
                x->left = temp->left;
                delete temp;
                temp = nullptr;
            }
        }
        x->N = size(x->left) + size(x->right) + 1;
        return x;
    }

    template <typename K, typename V>
    std::vector<K> ST::BST<K, V>::keyVec()
    {
        return keyVec(min(), max());
    }

    template <typename K, typename V>
    std::vector<K> ST::BST<K, V>::keyVec(const K &keysLo, const K &keysHi)
    {
        std::vector<K> queue;
        queue.reserve(rank(root, keysHi) - rank(root, keysLo) + 1);
        keyVec(root, queue, keysLo, keysHi);
        return queue;
    }

    template <typename K, typename V>
    void ST::BST<K, V>::keyVec(BNode<K, V> *x, std::vector<K> &queue, const K &keysLo, const K &keysHi)
    {
        if (x == nullptr)
        {
            return;
        }
        if (keysLo < x->key)
        {
            keyVec(x->left, queue, keysLo, keysHi);
        }
        if (keysLo <= x->key && keysHi >= x->key)
        {
            queue.push_back(x->key);
        }
        if (keysHi > x->key)
        {
            keyVec(x->right, queue, keysLo, keysHi);
        }
    }

} // namespace ST

#endif
举报

相关推荐

0 条评论