简述容器之rb_tree及其应用

  • 概述:
      Red-Black tree(红黑树)是平衡二分搜寻树(balanced binary search tree)中常被使用的一种平衡二分搜寻树的特征:排列规则有利于search和insert,并保持适度平衡————无任何结点太深。
       红黑树只要求局部平衡,C++ STL中的map、set、multimap、multiset都应用了红黑树。
      红黑树的每个节点或者上都有存储位表示节点的颜色,颜色是红或者黑,红黑树的特征有:1.每个节点或者是黑色或者是红色 2.根节点是黑色 3.每个叶子节点是黑色[这里叶子节点,是指为空的叶子节点] 4.如果一个节点是黑色的,那么它的子节点必须是黑色的 5.从一个节点到该节点的子节点的所有路径上包含相同数目的黑节点[注意:这里需要确保没有一条路径会比其他路径长出两倍]

  rb_tree提供“遍历”操作及iterators。按正常规则(++ite)遍历,便能获得排序状态(sorted)。
  我们不应使用rb_tree的iterators改变元素值(因为元素有其严谨的排列规则)。编程里面(programming leve)并未阻绝此事。如此设计是正确的,因为rb_tree即将为set和map服务(作为其底部支持),而map允许元素的data被改变,只有元素的key才是不可被改变的。
  rb_tree提供两种insertion操作:insert_unique()和insert_equal前者表示节点的key 一定在整个tree中独一无二,否则安插失败,后者表示节点的key可以重复。

image

  •   红黑树的基本操作是添加、删除和旋转。在对红黑树进行添加或者删除后,会用到旋转方法。因为添加或删除红黑树中的节点之后,红黑树就发生了变化,可能不满足红黑树的五条特性,也就不再是一颗红黑树了,而是一颗普通的树。而通过旋转,可以使这颗树重新成为红黑树。简单的说旋转的目的是为了让树保持红黑树的特性。
    以下为参考代码:
enum RBTColor{RED, BLACK};

template <class T>
class RBTNode{
    public:
        RBTColor color;    // 颜色
        T key;            // 关键字(键值)
        RBTNode *left;    // 左孩子
        RBTNode *right;    // 右孩子
        RBTNode *parent; // 父结点

        RBTNode(T value, RBTColor c, RBTNode *p, RBTNode *l, RBTNode *r):
            key(value),color(c),parent(),left(l),right(r) {}
};

template <class T>
class RBTree {
    private:
        RBTNode<T> *mRoot;    // 根结点

    public:
        RBTree();
        ~RBTree();

        // 前序遍历"红黑树"
        void preOrder();
        // 中序遍历"红黑树"
        void inOrder();
        // 后序遍历"红黑树"
        void postOrder();

        // (递归实现)查找"红黑树"中键值为key的节点
        RBTNode<T>* search(T key);
        // (非递归实现)查找"红黑树"中键值为key的节点
        RBTNode<T>* iterativeSearch(T key);

        // 查找最小结点:返回最小结点的键值。
        T minimum();
        // 查找最大结点:返回最大结点的键值。
        T maximum();

        // 找结点(x)的后继结点。即,查找"红黑树中数据值大于该结点"的"最小结点"。
        RBTNode<T>* successor(RBTNode<T> *x);
        // 找结点(x)的前驱结点。即,查找"红黑树中数据值小于该结点"的"最大结点"。
        RBTNode<T>* predecessor(RBTNode<T> *x);

        // 将结点(key为节点键值)插入到红黑树中
        void insert(T key);

        // 删除结点(key为节点键值)
        void remove(T key);

        // 销毁红黑树
        void destroy();

        // 打印红黑树
        void print();
    private:
        // 前序遍历"红黑树"
        void preOrder(RBTNode<T>* tree) const;
        // 中序遍历"红黑树"
        void inOrder(RBTNode<T>* tree) const;
        // 后序遍历"红黑树"
        void postOrder(RBTNode<T>* tree) const;

        // (递归实现)查找"红黑树x"中键值为key的节点
        RBTNode<T>* search(RBTNode<T>* x, T key) const;
        // (非递归实现)查找"红黑树x"中键值为key的节点
        RBTNode<T>* iterativeSearch(RBTNode<T>* x, T key) const;

        // 查找最小结点:返回tree为根结点的红黑树的最小结点。
        RBTNode<T>* minimum(RBTNode<T>* tree);
        // 查找最大结点:返回tree为根结点的红黑树的最大结点。
        RBTNode<T>* maximum(RBTNode<T>* tree);

        // 左旋
        void leftRotate(RBTNode<T>* &root, RBTNode<T>* x);
        // 右旋
        void rightRotate(RBT
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值