STL源码分析之红黑树

主要分析一下STL里的红黑树,红黑树相对来说是一种较为复杂的数据结构,具体的学习方法建议看那种带有很多图解的博客,先理解其原理流程,再自己写下代码,其实就能理解了。STL里红黑树的实现有几个特点,一个它设置了一个空头结点header,它的左节点指向树最小元素,有节点指向树最大元素,实际带有有意义值的头结点为root,root的父节点为header.这使在一些插入删除操作时要讨论下特殊情况,附上代码分析

//红色为false,黑色为true
typedef bool __rb_tree_color_type;
const __rb_tree_color_type __rb_tree_red = false;
const __rb_tree_color_type __rb_tree_black = true;

//红黑树节点
struct __rb_tree_node_base
{
    typedef __rb_tree_color_type color_type;
    typedef __rb_tree_node_base* base_ptr;  //指向节点的指针

    //该节点的颜色
    color_type color;
    //父节点
    base_ptr parent;
    //左孩子
    base_ptr left;
    //右孩子
    base_ptr right;

    //寻找最小值
    static base_ptr minimum(base_ptr x)
    {
        while (x->left != 0) x = x->left;
        return x;
    }

    //寻找最大值
    static base_ptr maximum(base_ptr x)
    {
        while (x->right != 0) x = x->right;
        return x;
    }
};

//节点模板
template <class Value>
struct __rb_tree_node : public __rb_tree_node_base
{
    typedef __rb_tree_node<Value>* link_type;
    Value value_field;
};


//迭代器
struct __rb_tree_base_iterator
{
    typedef __rb_tree_node_base::base_ptr base_ptr;
    //迭代器种类为bidirectional_iterator
    typedef bidirectional_iterator_tag iterator_category;
    typedef ptrdiff_t difference_type;
    base_ptr node;

    //寻找后继节点
    void increment()
    {
        /*若右子树没有左子树,后继就为该右子树
         * 若右子树有左结点,就为最左边节点
         */
        if (node->right != 0) {
            node = node->right;
            while (node->left != 0)
                node = node->left;
        }
        else {
            /*当该节点就为其父节点的左节点时,其后继节点就是其父节点
             * 当为右节点时,往上找是其根节点的左节点的节点,其后继节点就是这个节点的根节点
             * (有点绕,画图理解)
            */
            base_ptr y = node->parent;
            while (node == y->right) {
                node = y;
                y = y->parent;
            }
            if (node->right != y)
                node = y;
        }
    }
    //找前继节点
    void decrement()
    {
        if (node->color == __rb_tree_red &&
            node->parent->parent == node)
            node = node->right;
        else if (node->left != 0) {
            base_ptr y = node->left;
            while (y->right != 0)
                y = y->right;
            node = y;
        }
        else {
            base_ptr y = node->parent;
            while (node == y->left) {
                node = y;
                y = y->parent;
            }
            node = y;
        }
    }
};

//迭代器
template <class Value, class Ref, class Ptr>
struct __rb_tree_iterator : public __rb_tree_base_iterator
{
    //一些定义
    typedef Value value_type;
    typedef Ref reference;
    typedef Ptr pointer;
    typedef __rb_tree_iterator<Value, Value&, Value*>             iterator;
    typedef __rb_tree_iterator<Value, const Value&, const Value*> const_iterator;
    typedef __rb_tree_iterator<Value, Ref, Ptr>                   self;
    typedef __rb_tree_node<Value>* link_type;

    //构造函数
    __rb_tree_iterator() {}
    __rb_tree_iterator(link_type x) { node = x; }
    __rb_tree_iterator(const iterator& it) { node = it.node; }

    //重载* 和 ->操作符
    reference operator*() const { return link_type(node)->value_field; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
    pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */

    //重载++操作符
    self& operator++() { increment(); return *this; }
    self operator++(int) {
        self tmp = *this;
        increment();
        return tmp;
    }

    //重载--操作符
    self& operator--() { decrement(); return *this; }
    self operator--(int) {
        self tmp = *this;
        decrement();
        return tmp;
    }
};

template <class Key, class Value, class KeyOfValue, class Compare,
        class Alloc = alloc>
/* key红黑树上存储节点时依据的值
 * value节点的值
 * KeyOfValue仿函数
 * Compare为比较key大小的标准
 * Alloc空间配置器
 */
class rb_tree {
protected:
    typedef void *void_pointer;
    typedef __rb_tree_node_base *base_ptr;
    typedef __rb_tree_node<Value> rb_tree_node;
    //自带的配置函数
    typedef simple_alloc <rb_tree_node, Alloc> rb_tree_node_allocator;
    typedef __rb_tree_color_type color_type;
public:
    typedef Key key_type;
    typedef Value value_type;
    typedef value_type *pointer;
    typedef const value_type *const_pointer;
    typedef value_type &reference;
    typedef const value_type &const_reference;
    typedef rb_tree_node *link_type;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
protected:
    //获取一个新的节点
    link_type get_node() { return rb_tree_node_allocator::allocate(); }

    //释放指定节点
    void put_node(link_type p) { rb_tree_node_allocator::deallocate(p); }

    //创建一个节点,先申请内存然后构造
    link_type create_node(const value_type &x) {
        link_type tmp = get_node();
        __STL_TRY{
                construct(&tmp->value_field, x);
        }
        __STL_UNWIND(put_node(tmp));
        return tmp;
    }

    //复制节点
    link_type clone_node(link_type x) {
        link_type tmp = create_node(x->value_field);
        tmp->color = x->color;
        tmp->left = 0;
        tmp->right = 0;
        return tmp;
    }

    //销毁节点
    void destroy_node(link_type p) {
        destroy(&p->value_field);
        put_node(p);
    }

protected:
    size_type node_count;
    //header节点
    link_type header;
    //大小比较函数
    Compare key_compare;

    //获取头结点
    link_type &root() const { return (link_type &) header->parent; }

    //获取最小节点
    link_type &leftmost() const { return (link_type &) header->left; }

    //获取最大节点
    link_type &rightmost() const { return (link_type &) header->right; }

    //返回当前节点的左孩子
    static link_type &left(link_type x) { return (link_type &) (x->left); }

    static link_type &right(link_type x) { return (link_type &) (x->right); }

    static link_type &parent(link_type x) { return (link_type &) (x->parent); }

    //获取当前节点的value
    static reference value(link_type x) { return x->value_field; }

    //通过value获取当前节点的key
    static const Key &key(link_type x) { return KeyOfValue()(value(x)); }

    //获取当前节点的颜色
    static color_type &color(link_type x) { return (color_type &) (x->color); }

    static link_type &left(base_ptr x) { return (link_type &) (x->left); }

    static link_type &right(base_ptr x) { return (link_type &) (x->right); }

    static link_type &parent(base_ptr x) { return (link_type &) (x->parent); }

    static reference value(base_ptr x) { return ((link_type) x)->value_field; }

    static const Key &key(base_ptr x) { return KeyOfValue()(value(link_type(x))); }

    static color_type &color(base_ptr x) { return (color_type &) (link_type(x)->color); }

    //获取最小值和最大值
    static link_type minimum(link_type x) {
        return (link_type) __rb_tree_node_base::minimum(x);
    }

    static link_type maximum(link_type x) {
        return (link_type) __rb_tree_node_base::maximum(x);
    }

public:
    typedef __rb_tree_iterator<value_type, reference, pointer> iterator;
    typedef __rb_tree_iterator<value_type, const_reference, const_pointer>
            const_iterator;

private:
    //插入
    iterator __insert(base_ptr x, base_ptr y, const value_type &v);

    //复制
    link_type __copy(link_type x, link_type p);

    //删除
    void __erase(link_type x);

    //初始化,申请一空头结点
    void init() {
        header = get_node();
        color(header) = __rb_tree_red;
        root() = 0;
        leftmost() = header;
        rightmost() = header;
    }

public:
    //构造函数
    rb_tree(const Compare &comp = Compare())
            : node_count(0), key_compare(comp) { init(); }

    //拷贝构造函数
    rb_tree(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &x)
            : node_count(0), key_compare(x.key_compare) {
        header = get_node();
        color(header) = __rb_tree_red;
        if (x.root() == 0) {
            root() = 0;
            leftmost() = header;
            rightmost() = header;
        } else {
            __STL_TRY{
                    root() = __copy(x.root(), header);
            }
            __STL_UNWIND(put_node(header));
            leftmost() = minimum(root());
            rightmost() = maximum(root());
        }
        node_count = x.node_count;
    }

    ~rb_tree() {
        clear();
        put_node(header);
    }

    //重载操作符=,即赋值
    rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &
    operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &x);

    //重载操作符==
    template<class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    inline bool operator==(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &x,
                           const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &y) {
        return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
    }

public:
    Compare key_comp() const { return key_compare; }

    //起始迭代器是最小节点,即header结点的左节点
    iterator begin() { return leftmost(); }

    const_iterator begin() const { return leftmost(); }

    //末尾迭代器是header
    iterator end() { return header; }

    const_iterator end() const { return header; }

    //判断是否为空
    bool empty() const { return node_count == 0; }

    //节点个数
    size_type size() const { return node_count; }

    size_type max_size() const { return size_type(-1); }
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::
__insert(base_ptr x_, base_ptr y_, const Value& v) {
    /* x为新的插入点
     * y为要插入的点的父节点
     * v为插入的值
     */
    link_type x = (link_type) x_;
    link_type y = (link_type) y_;
    link_type z;

    //y为header或x不为空或者要插入的值的key与y不重复
    if (y == header || x != 0 || key_compare(KeyOfValue()(v), key(y))) {
        //创建并初始化值为v的节点,为红色
        z = create_node(v);
        //将header的左孩子设置为z
        left(y) = z;
        if (y == header) {

            root() = z;
            rightmost() = z;
        }
        else if (y == leftmost())
            leftmost() = z;
    }
    else {
        //否则创建值为v的节点
        z = create_node(v);
        //将y的右孩子设置为z
        right(y) = z;
        //更新最大点
        if (y == rightmost())
            rightmost() = z;
    }
    //设置新节点的父节点、左孩子节点、右孩子节点
    parent(z) = y;
    left(z) = 0;
    right(z) = 0;
    //平衡调节
    __rb_tree_rebalance(z, header->parent);
    //节点数加1
    ++node_count;
    //返回迭代器指向新增节点
    return iterator(z);
}

//左旋
inline void
__rb_tree_rotate_left(__rb_tree_node_base* x, __rb_tree_node_base*& root)
{

    __rb_tree_node_base* y = x->right;
    x->right = y->left;
    if (y->left !=0)
        //将左子节点的父节点设置为x
        y->left->parent = x;
    y->parent = x->parent;

    //将x的位置替换成y
    if (x == root)
        root = y;
    else if (x == x->parent->left)
        x->parent->left = y;
    else
        x->parent->right = y;
    y->left = x;
    x->parent = y;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章