红黑树的原理和实现(STL源码剖析/C++)

红黑树的定义

  1. 每个节点要么是红色,要么是黑色
  2. 根节点是黑色
  3. 所有叶子节点(NULL)为黑色 (这里的叶子节点是指空节点NIL或者NULL,可以理解为虚拟的叶子节点)
  4. 如果一个节点是红色,则它的子节点必须是黑色的(没有两个相邻的红色节点)
  5. 从一个节点到该节点的子孙节点的所有路径有相同数目的黑色节点 (保证最长路径不会超过最短的两倍

红黑树的时间复杂度

  • 红黑树的时间复杂度O(logn)
    红黑树的查找、插入、删除都可以在O(logn)内完成

定理:一棵含有n个节点的红黑树的高度至多为2log(n+1).
如图: n = 6
h = 4
CSDN图标

红黑树和AVL树的区别

思考:为什么大多数库函数使用红黑树实现而不是AVL树。比如C++ 中的 map 和 set ,或者 Java 中的 TreeSet 和 TreeMap

首先了解AVL树的定义:
AVL树本质上还是一棵二叉搜索树

  • 本身首先是一棵二叉搜索树。
  • 带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。

从红黑树的定义和AVL树的定义可以看出它们的区别:

  • AVL 树比红黑树更加平衡,但AVL树在插入和删除的时候也会存在大量的旋转操作。所以当你的应用涉及到频繁的插入和删除操作,切记放弃AVL树,选择性能更好的红黑树;当然,如果你的应用中涉及的插入和删除操作并不频繁,而是查找操作相对更频繁,那么就优先选择 AVL 树进行实现。

红黑树的实现分析

数据结构

如下图所示,一个节点包含一个左孩子left和右孩子right以及一个parent指针。为了方便实现红黑树还有一个header节点,它也包含这三个指针,但代表的意思不一样,header的parent是指向root节点的,left指向最小值节点,right指向最大值节点。
CSDN图标

数据结构代码实现

思考:__rb_tree_node继承了__rb_tree_node_base,继承的关系可以理解为__rb_tree_node是__rb_tree_node_base,也就是说对于所有接受__rb_tree_node_base对象为参数的函数,也会接受__rb_tree_node的对象作为参数。
这样做的意义是:在对红黑树进行操作时,如果不涉及数据操作,就可以忽略数据成员,比如在红黑树平衡过程中,只需考虑节点颜色,节点的位置已经确定了节点的数据大小,这时候就不需要value成员。
注意:每个节点被创建时应该是__rb_tree_node类型。

#pragma once

namespace MiniSTL {

using rb_tree_color_type = bool;
const rb_tree_color_type rb_tree_red = false;
const rb_tree_color_type rb_tree_black = true;

struct __rb_tree_node_base {
    using color_type = rb_tree_color_type;
    using base_ptr = __rb_tree_node_base *;
    // data member
    color_type color;
    base_ptr parent;
    base_ptr left;
    base_ptr right;
    // get mix/max ptr
    static base_ptr minimum(base_ptr root) {
        while (root->left) root = root->left;
        return root;
    }
    static base_ptr maximum(base_ptr root) {
        while (root->right) root = root->right;
        return root;
    }
};
template <class T>
struct __rb_tree_node : public __rb_tree_node_base {
    using link_type = __rb_tree_node<T> *;
    T value_field;
};
}

迭代器

假设it是红黑树的迭代器,执行代码:
it = begin(); while (it != end()) ++it;
迭代器it的遍历过程如下图所示it0-it8
CSDN图标

迭代器代码实现

#pragma once

#include <cstddef>
#include "rb_tree_node.h"
#include <iterator>

namespace MiniSTL
{

struct rb_tree_base_iterator {
    using base_ptr = __rb_tree_node_base::base_ptr;
    using iterator_category = std::bidirectional_iterator_tag;
    using difference_type = ptrdiff_t;

    base_ptr node;
    // 供重载操作符++使用,node不可能直接为header
    // 顺序移动到下一个位置
    void increment() {
        // 存在右节点,则下一节点比为右子树的最左下角
        if (node->right) {
            node = node->right;
            while (node->left) node = node->left;
        } else { // 没有右节点,则应该是不断上溯,第一个不为右子节点的祖先
            while (node->parent->right == node) // 到根节点root不是header也会跳出循环
                node = node->parent;
            
            // 最右边节点的下一个节点应该是header
            // 只有一种情况node会到header,就是迭代器指向root,并且无右节点
            if (node->right != node->parent) node = node->parent;
            // 当node等于header时,就等于header
        }
    }

    // 供重载操作符--使用,
    // 前一个位置
    void decrement() {
        // header理解为最后一个节点
        // 当node为header时
        if (node->color == rb_tree_red && node->parent->parent == node) {
            node = node->right;
        } else if (node->left) // 存在左子节点
        {
            base_ptr l = node->left;
            while (l->right) l = l->right;
            node = l;
        } else { // 非header,无左子
            base_ptr p = node->parent;
            while (node == p->left) {
                node = p;
                p = p->parent;
            }
            node = p;
        }
    }
};

template <class T, class Ref, class Ptr>
struct rb_tree_iterator : public rb_tree_base_iterator {
    using value_type = T;
    using reference = Ref;
    using pointer = Ptr;
    using iterator = rb_tree_iterator<T, T &, T *>;
    using const_iterator = rb_tree_iterator<T, const T &, const T *>;
    using self = rb_tree_iterator<T, Ref, Ptr>;
    using link_type = __rb_tree_node<T> *;

    rb_tree_iterator() {}
    rb_tree_iterator(link_type x) { node = x; }
    rb_tree_iterator(const iterator &it) { node = it.node; }

    reference operator*() const {
        return reinterpret_cast<link_type>(node)->value_field;
    }

    pointer operator->() const {
        return &(operator*());
    }

    // 前闭后开,最后一个元素可以++,然后为header
    self &operator++() {
        increment();
        return *this;
    }

    self operator++(int) {
        self temp = *this;
        increment();
        return temp;
    }
    //node不能为最小节点
    self &operator--() {
        decrement();
        return *this;
    }
    self operator--(int) {
        self temp = *this;
        decrement();
        return temp;
    }
};

template <class T, class Ref, class Ptr>
inline bool operator==(const rb_tree_iterator<T, Ref, Ptr> &lhs, 
    const rb_tree_iterator<T, Ref, Ptr> &rhs) {
    return lhs.node == rhs.node;
}

template <class T, class Ref, class Ptr>
inline bool operator!=(const rb_tree_iterator<T, Ref, Ptr> &lhs, 
    const rb_tree_iterator<T, Ref, Ptr> &rhs) {
    return lhs.node != rhs.node;
}
}

插入操作

注意:每次插入的节点颜色为蓝色,并且在叶子节点。
只有父节点为红色时才需要调整平衡。

一:父亲为祖父的左孩子

  • 情况一:叔叔为红色
    方法:调整祖父颜色为红色,叔叔和父亲为黑色。因为祖父的颜色由黑变红可能会破坏上层平衡,所以把当前节点设置为祖父节点,继续调成平衡。
    在这里插入图片描述
  • 情况二:叔叔为黑色,子是父节点的左孩子
    方法:RR,
    1、调整颜色祖父:红色父亲:黑色。
    2、以祖父节点右旋。此时上层节点父节点是黑色,不会破坏上层平衡,停止调整。
    在这里插入图片描述
  • 情况三:叔叔为黑色,子是父节点的右孩子
    方法:LR
    1、以父节点左旋。
    2、调整子父节点指针为右下图所指(旋转后位置互换了),此时回到情况二。
    3、调整颜色祖父:红色父亲:黑色。
    4、以祖父节点右旋。此时上层节点父节点是黑色,不会破坏上层平衡,停止调整。在这里插入图片描述在这里插入图片描述
    一:父亲为祖父的右孩子
    这与上述所有情况相对,就不画图了,可看代码。

删除操作

注意:删除操作应该包含两个部分,查找、删除与自平衡。

二叉树删除结点找替代结点有3种情况:

  • 情况1:若删除结点无子结点,直接删除。
  • 情况2:若删除结点只有一个子结点,用子结点替换删除结点。
  • 情况3:若删除结点有两个子结点,用后继结点(大于删除结点的最小结点)替换(这里使用值交换)删除结点。

思考:最终被删除的节点,应该是最多有一个孩子。如果删除节点是红色,不会破坏平衡,也就是说,只有删除节点是黑色时才会破坏平衡,因为包含删除节点的路径少了一个黑色节点。

前提条件: 最终删除节点是黑色,替换节点x为黑色(或者NULL),替换节点是指现在在删除节点原有位置的节点
思考: x子树少一个黑色节点,下面开始平衡。
一:x是父亲的左孩子

  • 情况一:x的兄弟节点是红色(可知x的父节点和兄弟节点的孩子节点都是红色)
  • 方法:
    (01) 将x的兄弟节点设为“黑色”。
    (02) 将x的父节点设为“红色”。
    (03) 对x的父节点进行左旋。
    (04) 左旋后,重新设置x的兄弟节点。
    此时x还是少一个黑色节点,只是进入另一种状态继续调整。
    在这里插入图片描述
    在这里插入图片描述
  • 情况二:x的兄弟节点是黑色,x的兄弟节点的两个孩子都是黑色。
  • 方法
    (01) 将x的兄弟节点设为“红色”。
    (02) 设置“x的父节点”为“新的x节点”。
    x的父节点此时整体少一个黑色节点,所以成为新的x节点。
    在这里插入图片描述
  • 情况三:x的兄弟节点是黑色;x的兄弟节点的左孩子是红色,右孩子是黑色的。
  • 方法
    (01) 将x兄弟节点的左孩子设为“黑色”。
    (02) 将x兄弟节点设为“红色”。
    (03) 对x的兄弟节点进行右旋。
    (04) 右旋后,重新设置x的兄弟节点。
    此时到达情况四
    在这里插入图片描述
  • 情况四:x的兄弟节点是黑色;x的兄弟节点的右孩子是红色的,x的兄弟节点的左孩子任意颜色。
  • 方法
    (01) 将x父节点颜色 赋值给 x的兄弟节点。
    (02) 将x父节点设为“黑色”。
    (03) 将x兄弟节点的右子节设为“黑色”。
    (04) 对x的父节点进行左旋。
    (05) 设置“x”为“根节点”。
    从图片可以看出,原本的x子树已经在原来的情况下多了一个黑色节点,所以平衡已经完成,x设置为根节点,是一个停止循环的操作。
    在这里插入图片描述
    二:x是父亲的右孩子
    与上面的删除平衡过程相对应,可看代码。

红黑树操作代码

#pragma once
 
#include <memory>
#include <new>
#include <algorithm>
#include <functional>
#include "rb_tree_iterator.h"

namespace MiniSTL
{

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc = std::allocator<Value>>
class rb_tree {
private:
    using base_ptr = __rb_tree_node_base *;
    using rb_tree_node = __rb_tree_node<Value>;
    using rb_tree_node_allocator = std::allocator<rb_tree_node>;
    using color_type = rb_tree_color_type;

public:
    using key_type = Key;
    using value_type = Value;
    using pointer = value_type *;
    using const_pointer = const value_type *;
    using reference = value_type &;
    using const_reference = const value_type &;
    using link_type = rb_tree_node *;
    using size_type = size_t;
    using difference_type = ptrdiff_t;

    // Iterator
    using iterator = rb_tree_iterator<value_type, value_type &, value_type *>;
    using const_iterator = rb_tree_iterator<value_type, const_reference, const_pointer>;

private: // operation of node
    // 分配内存
    link_type get_node() { 
        std::allocator<__rb_tree_node<Value>> sp;
        link_type p = sp.allocate(sizeof(__rb_tree_node<Value>));
        return p;
    }
    // 释放内存
    void put_node(link_type p) {
        std::allocator<__rb_tree_node<Value>> sp;
        sp.deallocate(p, sizeof(__rb_tree_node<Value>));
    }
    //
    link_type create_node(const value_type &val) {
        link_type temp = get_node();
        try {
            new (&temp->value_field) value_type(val);
    
        } catch (std::exception &) {
            put_node(temp);
        }
        return temp;
    }
    // 克隆节点,包括颜色
    link_type clone_node(link_type p) {
        link_type temp = create_node(p->value_field);
        temp->color = p->color;
        temp->left = nullptr;
        temp->right = nullptr;
        return temp;
    }


    void destroy_node(link_type p) {
        Value *vp = &(p->value_field);
        vp->~Value();
        put_node(p);
    }

private: // data member
    size_type node_count;
    link_type header;
    Compare key_compare;

private: // data member getter && setter
    // header成员
    link_type &root() const noexcept {
        return reinterpret_cast<link_type &>(header->parent);
    }
    // head->left指向的是最小值
    link_type &leftmost() const noexcept {
        return reinterpret_cast<link_type &>(header->left);
    }
    // head->right指向的是最大值
    link_type &rightmost() const noexcept {
        return reinterpret_cast<link_type &>(header->right);
    }

    // 普通node的快速访问与设定
    //  静态成员函数的作用在于:调用这个函数不会
    // 访问或者修改任何对象(非static)数据成员。
    static link_type &left(link_type p) {
        return reinterpret_cast<link_type &>(p->left);
    }
    static link_type &right(link_type p) {
        return reinterpret_cast<link_type &>(p->right);
    }
    static link_type &parent(link_type p) {
        return reinterpret_cast<link_type &>(p->parent);
    }
    static reference &value(link_type p) {
        return p->value_field;
    }
    static const Key &key(link_type p) { 
        return KeyOfValue()(value(p));
    }
    static color_type &color(link_type p) { return p->color; }
    
    // base_node 的快速访问和设定
    static link_type &left(base_ptr p) {
        return reinterpret_cast<link_type &>(p->left);
    }
    static link_type &right(base_ptr p) {
        return reinterpret_cast<link_type &>(p->right);
    }
    static link_type &parent(base_ptr p) {
        return reinterpret_cast<link_type &>(p->parent);
    }

    static reference &value(base_ptr p) {
        return reinterpret_cast<link_type &>(p)->value_field;
    }
    static const Key &key(base_ptr p) { 
        return KeyOfValue()(value(reinterpret_cast<link_type &>(p)));
    }
    static color_type &color(base_ptr p) { 
        return reinterpret_cast<link_type &>(p)->color; 
    }

    // 求取极值
    static link_type minimum(link_type p) {
        return reinterpret_cast<link_type>(
            __rb_tree_node_base::minimum(p));
    }
    static link_type maximum(link_type p) {
        return reinterpret_cast<link_type>(
            __rb_tree_node_base::maximum(p));
    }
private: // aux interface
    link_type copy(link_type, link_type);
    void empty_initialize() {
        header = get_node();
        color(header) = rb_tree_red;
        root() = nullptr;
        leftmost() = header;
        rightmost() = header;
    }    

private: // rotate && rebalance
    void rb_tree_rotate_left(base_ptr, base_ptr &);
    void rb_tree_rotate_right(base_ptr, base_ptr &);
    void rb_tree_rebalance(base_ptr, base_ptr &);
    base_ptr rb_tree_rebalance_for_erase(base_ptr, base_ptr &, 
        base_ptr &, base_ptr &);

public: // ctor && dtor
    // key_compare()调用compare的默认构造
    rb_tree() : node_count(0), key_compare() { empty_initialize(); }
    explicit rb_tree(const Compare &comp) : node_count(0), key_compare(comp) {
        empty_initialize();
    }
    ~rb_tree() {
        clear();
        put_node(header);
    }

public: // copy operation, 
    rb_tree(const rb_tree &rhs) : node_count(0), key_compare(rhs.key_compare) {
        // 创建一个header并完成初始化
        if (!rhs.root())
            empty_initialize();
        else {
            header = get_node();
            color(header) = rb_tree_red;
            root() = copy(rhs.root(), header);
            leftmost() = minimum(root());
            rightmost() = maximum(root());
        }
        node_count = rhs.node_count;
    }

    rb_tree &operator=(const rb_tree &);

public: // move operation
     rb_tree(rb_tree &&rhs) noexcept {
        empty_initialize();
        swap(rhs);
    }

    rb_tree &operator=(rb_tree &&rhs) noexcept {
        clear();
        swap(rhs);
        return *this;
    }

public: // getter
    // 返回的时候会自动调用const_iterator(leftmost())
    const_iterator begin() const noexcept { return leftmost(); }
    const_iterator end() const noexcept { return header; }
    const_iterator cbegin() const noexcept { return leftmost(); }
    const_iterator cend() const noexcept { return header; }
    bool empty() {
        return node_count == 0;
    }
    size_type size() const noexcept {
        return node_count;
    }

public:
    iterator begin() noexcept { return leftmost(); }
    iterator end() noexcept { return header; }
    
private: // aux interface for insert
    iterator insert_aux(base_ptr, base_ptr, const value_type &);

public: // insert
    std::pair<iterator, bool> insert_unique(const value_type &);
    iterator insert_unique(iterator, const value_type &);
    template <class InputIterator>
    void insert_unique(InputIterator, InputIterator);
    iterator insert_equal(iterator, const value_type &);
    iterator insert_equal(const value_type &);
    template <class InputIterator>
    void insert_equal(InputIterator, InputIterator);

private: // aux interface for erase
    void erase_aux(link_type) noexcept;

public: // erase;
    void erase(iterator);
    size_type erase(const key_type &);
    void erase(iterator, iterator);
    void clear() noexcept;

public: // find
    iterator find(const key_type &) noexcept;
    const_iterator find(const key_type &) const noexcept;
    size_type count(const key_type &) const noexcept;
    iterator lower_bound(const key_type &)  noexcept;
    const_iterator lower_bound(const key_type &) const noexcept;
    iterator upper_bound(const key_type &)  noexcept;
    const_iterator upper_bound(const key_type &) const noexcept;
    std::pair<iterator, iterator> equal_range(const key_type &) noexcept;
    std::pair<const_iterator, const_iterator> equal_range(const key_type &) const noexcept;

public: // swap
    void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &rhs) {
        std::swap(header, rhs.header); // header也是指针
        std::swap(node_count, rhs.node_count);
        std::swap(key_compare, rhs.key_compare);
    }

};


// ----------------------------insert-------------
// 每次有新数据插入,一定是先在叶子节点插入
// 该接口只做插入操作,把val插入到y的左孩子或者右孩子
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_aux(base_ptr x_, base_ptr y_, const value_type &val) {
    link_type x = reinterpret_cast<link_type>(x_);
    link_type y = reinterpret_cast<link_type>(y_);
    link_type z;
    // 先满足左边插入
    // 
    if (y == header || x || key_compare(KeyOfValue()(val), key(y))) {
        z = create_node(val);
        left(y) = z;
        if (y == header) {
            root() = z;
            rightmost() = z;
        } else if (y == leftmost()){
            leftmost() = z;
        }
    } else  {
        z = create_node(val);
        right(y) = z;
        if (rightmost() == y) {
            rightmost() = z;
        }
    }
    // 更新z的节点指针
    parent(z) = y;
    // 插入节点之后需要检查是否破坏平衡
    rb_tree_rebalance(z, header->parent);
    ++node_count;
    return iterator(z);
} 

// 节点插入后需要重新维护这棵树
// 不涉及val就可以直接使用base_ptr节点类型
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
void
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::rb_tree_rebalance(base_ptr x, base_ptr &root) {
    // 会调用这个函数,那当前节点应该是红色,才会调整
    x->color = rb_tree_red;
    // 需要向上调整的情况, 非根节点且父节点为红色
    // 从这个条件可以看出 x->parent != root,显然最多祖父到root节点
    while (x != root && x->parent->color == rb_tree_red) {
        // 考虑父亲是祖父的哪一个孩子
        // 情况一:父亲为祖父的左子
        if (x->parent == x->parent->parent->left) {
            // 考虑叔叔的颜色
            base_ptr y = x->parent->parent->right;
            // 1、叔叔存在且为红色
            if (y && y->color == rb_tree_red) 
            {
                // 直接调整颜色父亲,叔叔为黑色,祖父调为红色
                x->parent->color = rb_tree_black;
                y->color = rb_tree_black;
                x->parent->parent->color = rb_tree_red;
                // 这个时候祖父需要作为当前节点被调整
                x = x->parent->parent;
            } 
            else // 2、叔叔不存在或为黑色,是同一种情况,因为nullptr被看作虚拟叶子节点,是黑色
            {
                //(1)我是父亲的右孩子,需要先L(左旋)再R(右旋)
                if (x == x->parent->right) {
                    // 左旋
                    x = x->parent; // 旋转之后才能继续作为孩子节点
                    // x是需要旋转节点的最上面的节点
                    rb_tree_rotate_left(x, root);
                } 
                // (2) 现在x在左边
                // 先把颜色互换,再旋转就平衡了
                x->parent->color = rb_tree_black;
                x->parent->parent->color = rb_tree_red;
                // 右旋
                rb_tree_rotate_right(x->parent->parent, root);
            }
        }
        else // 情况二:父亲为祖父的右子
        {
            // 考虑叔叔的颜色
            base_ptr y = x->parent->parent->left;
            // 1、叔叔存在且为红色
            if (y && y->color == rb_tree_red)
            {
                // 直接调整颜色父亲,叔叔为黑色,祖父调为红色
                x->parent->color = rb_tree_black;
                y->color = rb_tree_black;
                x->parent->parent->color = rb_tree_red;
                // 这个时候祖父需要作为当前节点被调整
                x = x->parent->parent;
            }
            else // 2、叔叔不存在或为黑色,是同一种情况,因为nullptr被看作虚拟叶子节点,是黑色
            {
                //(1)我是父亲的左孩子,需要先R(右旋)在L(左旋)
                if (x == x->parent->left)
                {
                    // 右旋
                    x = x->parent; // 旋转之后才能继续作为孩子节点
                    // x是需要旋转节点的最上面的节点
                    rb_tree_rotate_right(x, root);
                }
                // (2) 现在x在右边
                // 先把颜色互换,再旋转就平衡了
                x->parent->color = rb_tree_black;
                x->parent->parent->color = rb_tree_red;
                // 右旋
                rb_tree_rotate_left(x->parent->parent, root);
            }
        }
    }
    // 根节点一定为黑色
    root->color = rb_tree_black;
}

// 左旋
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline void
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::rb_tree_rotate_left(base_ptr x, base_ptr &root) {
    // 旋转节点右子
    base_ptr y = x->right;
    // 右子的左孩子移到当前节点的右子
    x->right = y->left;
    if (y->left) y->left->parent = x; // y->left处理完

    // 处理x->parent
    y->parent = x->parent;
    if (x == root) // x->parent == header
        root = y; // 相当于root存的地址直接变成了y
    else if (x == x->parent->left)
        x->parent->left = y;
    else 
        x->parent->right = y;
    
    // 处理y
    y->left = x;
    x->parent = y;

}

// 右旋
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline void
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::rb_tree_rotate_right(base_ptr x, base_ptr &root) {
    // 旋转节点左子
    base_ptr y = x->left;
    // 左子的右孩子移到当前节点的左子
    x->left = y->right;
    if (y->right) y->right->parent = x;

    y->parent = x->parent;
    // root == x;
    if (x == root) {
        root = y;
    } else if (x->parent->left == x)
    {
        x->parent->left = y;
    } else {
        x->parent->right = y;
    }

    y->right = x;
    x->parent = y;
}

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>::find(const key_type &k) noexcept {
    link_type y = header; // 最后一个不小于k的节点
    link_type x = root();
    // find找到的应该是最左边等于k的节点
    while (x) {
        if (!key_compare(key(x), k)) {
            y = x;
            x = left(x);
        } else {
            x = right(x);
        }
    }
    iterator j = iterator(y);
    // 没找到就返回end()
    return (j == end()) || key_compare(k, key(j.node)) ? end() : j;
}


template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find(const key_type &k) const noexcept {
    link_type y = header; // 最后一个不小于k的节点
    link_type x = root();
    // find找到的应该是最左边等于k的节点
    while (x) {
        if (!key_compare(key(x), k)) {
            y = x;
            x = left(x);
        } else {
            x = right(x);
        }
    }
    const_iterator j = const_iterator(y);
    // 没找到就返回end()
    return (j == end()) || key_compare(k, key(j.node)) ? end() : j;
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type 
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::count(const key_type &k) const noexcept {
    std::pair<iterator, iterator> p = equal_range(k);
    return std::distance(p.first, p.second);
}

// lower_bound(k)  it >= k;
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>::lower_bound(const key_type &k) noexcept {
    link_type y = header; //y >= k
    link_type x = root();

    while (x) {
        if (!key_compare(key(x), k)) {
            y = x;
            x = left(x);
        } else {
            x = right(x);
        }
    }
    return iterator(y);
}

// lower_bound(k)  it >= k;
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound(const key_type &k) const noexcept {
    link_type y = header; //y >= k
    link_type x = root();

    while (x) {
        if (!key_compare(key(x), k)) {
            y = x;
            x = left(x);
        } else {
            x = right(x);
        }
    }
    return const_iterator(y);
}

// upper_bound(k)  it > k;
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>::upper_bound(const key_type &k) noexcept {
    link_type y = header; //y > k y在最右边
    link_type x = root();

    while (x) {
        if (key_compare(k, key(x))) {
            y = x;
            x = left(x);
        } else {
            x = right(x);
        }
    }
    return iterator(y);
}


// upper_bound(k)  it > k;
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound(const key_type &k) const noexcept {
    link_type y = header; //y > k y在最右边
    link_type x = root();

    while (x) {
        if (key_compare(k, key(x))) {
            y = x;
            x = left(x);
        } else {
            x = right(x);
        }
    }
    return const_iterator(y);
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline std::pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, 
    typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::equal_range(const key_type &k) noexcept {
    return std::pair<iterator, iterator>(lower_bound(k), upper_bound(k));
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline std::pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator, 
    typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::equal_range(const key_type &k) const noexcept {
    return std::pair<const_iterator, const_iterator>(lower_bound(k), upper_bound(k));
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::operator=(const rb_tree &rhs) {
    if (this != &rhs) {
        clear(); // 释放的是root()的所有节点,header回到初始化
        key_compare = rhs.key_compare;
        if (rhs.root()) {
            root() = copy(rhs.root(), header);
            leftmost() = minimum(root());
            rightmost() = maximum(root());
            node_count = rhs.node_count;
        }
    }
    return *this;
}

// 只插入原本不存在的数据
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
std::pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, bool> 
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique(const value_type &val) {
    link_type y = header;
    link_type x = root();

    bool comp = true;
    while (x) {
        y = x;
        comp = key_compare(KeyOfValue()(val), key(x));
        x = comp ? left(x) : right(x);
    }
    iterator j(y);
    // y为待插入节点的父节点,并且为叶子节点
    if (comp) { // 插入父节点的左孩子
        if (j == begin())
            return std::pair<iterator, bool>(insert_aux(x, y, val), true);
        else  // j是待插入节点的父节点,--j是j的前一个节点
             // --j <= val < j, 
            --j; // j <= val
    }
    // val >= j
    if (key_compare(key(j.node), KeyOfValue()(val)))
        return std::pair<iterator, bool>(insert_aux(x, y, val), true);
    return std::pair<iterator, bool>(j, false); // 重复值
}

// 
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_unique(iterator pos, const value_type &val) {
    if (pos.node == header->left) { // begin()
        if (size() > 0 && key_compare(KeyOfValue()(val), key(pos.node)))
            return insert_aux(pos.node, pos.node, val);
        else 
            return insert_unique(val).first;
    } else if (pos.node == header) { // end()
        if (key_compare(key(rightmost()), KeyOfValue()(val)))
            return insert_aux(nullptr, rightmost(), val);
        else
            return insert_unique(val).first;
    } else {
        iterator before = pos;
        --before;
        // before < val && val < pos
        if (key_compare(key(before.node), KeyOfValue()(val) &&
            key_compare(KeyOfValue()(val), key(pos.node)))) {
            // before是pos的左孩子的最右边的节点
            if (!right(before.node)) {
                return insert_aux(nullptr, before.node, val);
            } else { // before是pos的祖先节点
                return insert_aux(pos.node, pos.node, val);
            }
        } else {
            return insert_unique(val).first;
        }
    }
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
template <class InputIterator> 
void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique(
    InputIterator first, InputIterator last) {
    for (; first != last; ++first) insert_unique(*first);
}

// 可以插入相同的元素
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_equal(const value_type &val) {
    link_type y = header;
    link_type x = root();
    while (x) {
        y = x;
        x = key_compare(KeyOfValue()(val), key(x)) ? left(x) : right(x);
    }
    return insert_aux(x, y, val);
}

// 某位置插入某值
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_equal(iterator pos, const value_type &val) {
    // 插入位置[begin(), end()]
    if (pos.node == header->left) { // begin()
        if (key_compare(KeyOfValue()(val), key(pos.node)))
            return insert_aux(pos.node, pos.node, val);
        else
            insert_equal(val);
    } else if (pos.node == header) {
        // 右边直接插入val >= rightmost()
        if (!key_compare(KeyOfValue()(val), key(rightmost())))
            return insert_equal(nullptr, rightmost(), val);
        else 
            return insert_equal(val);
    } else {
        iterator before = pos;
        --before;
        
        // before <= val <= pos
        if (!key_compare(KeyOfValue()(val), key(before.node) && 
            !key_compare(key(pos.node), KeyOfValue()(val)))) 
            // before是pos的左边孩子的最右节点
            if (!right(before.node))
                return insert_aux(nullptr, before.node, val);
            else // pos没有左边孩子
                return insert_aux(pos.node, pos.node, val);
        // pos是before右边孩子的最左节点
        else {
            // val < before || val > pos
            // 没有办法直接插入
            return insert_equal(val);
        }
    }
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
template <class InputIterator> 
void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_equal(
    InputIterator first, InputIterator last) {
    for (; first != last; ++first) insert_equal(*first);
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::link_type 
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::copy(link_type source_x, link_type obj_p)
{
    link_type top = clone_node(source_x);
    top->parent = obj_p; // 复制好每个节点的父指针

    try
    {
        // 回溯法,先处理右边节点
        if (source_x->right != nullptr)
        {
            // top就是下一个复制节点的父亲
            top->right = copy(right(source_x), top);
            // 上面结束代表top的右边子树已经建好
            obj_p = top;
            source_x = left(source_x);

            // 建好top的左树
            while (source_x != nullptr)
            {
                link_type y = clone_node(source_x);
                obj_p->left = y;
                y->parent = obj_p;
                if (source_x->right)
                    y->right = copy(right(source_x), y);
                obj_p = y;
                source_x = left(source_x);
            }
        }
    }
    catch (std::exception &)
    {
        erase_aux(top);
    }
    return top;
}

// ----------------delete-----------------------

// 单纯删除节点
// 回收包含x节点的整棵子树
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
void 
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase_aux(link_type x) noexcept {
    while (x) {
        erase_aux(right(x));
        link_type y = left(x);
        destroy_node(x);
        x = y;
    }
}

// 给外界的erase,需要保持平衡
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
void 
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator pos) {
    link_type y = reinterpret_cast<link_type>(rb_tree_rebalance_for_erase(
        pos.node, header->parent, header->left, header->right));
    destroy_node(y);
    --node_count;
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(const key_type &k) {
    std::pair<iterator, iterator> p = equal_range(k);
    size_type n = std::distance(p.first, p.second);
    erase(p.first, p.second);
    return n;
}

// 保持平衡的删除
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
void 
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator first, iterator last) {
    if (first == begin() && last == end()) {
        clear();
    } else {
        while(first != last) erase(first++);
    }
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
void 
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::clear() noexcept {
    if (node_count) {
        erase_aux(root());
        root() = nullptr;
        leftmost() = header;
        rightmost() = header;
        node_count = 0;
    }
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::base_ptr
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::rb_tree_rebalance_for_erase(
    base_ptr z, base_ptr &root, base_ptr &leftmost, base_ptr &rightmost) {
    // 删除z节点
    base_ptr y = z; //需要删除的节点
    base_ptr x = nullptr;
    base_ptr x_parent = nullptr;

    // 
    if (!y->left) { // 无左孩子
        x = y->right;
    } else { // 一定有左孩子
        if (!y->right) {
            x = y->left;
        } else { // 有两个孩子,用后继节点替换
            y = y->right;
            while(y->left) y = y->left;
            x = y->right;
        }
    }
    // y != z,那么z一定有两个孩子
    if (y != z) {
        // 直接把z的数据赋值为y
        reinterpret_cast<link_type>(z)->value_field = 
        reinterpret_cast<link_type>(y)->value_field;
        z = y;
    }
    // 把要删除节点的孩子提上来
    x_parent = y->parent;
    if (x) x->parent = y->parent;
    if (root == z) { // 要删除的节点是根节点
        root = x;
    } else if (z->parent->left == z) {
        z->parent->left = x;
    } else {
        z->parent->right = x;
    }
    if (leftmost == z) {
        if (!z->right) 
            leftmost = z->parent;
        else
            leftmost = __rb_tree_node_base::minimum(x);
    }
    if (rightmost == z) {
        if (!z->left)
            rightmost = z->parent;
        else 
            rightmost = __rb_tree_node_base::maximum(x);
    }
    // 平衡颜色
    // 删除红色节点不会破坏平衡
    // 删除节点颜色为黑色,则它一定有兄弟节点,不然黑色不平衡
    if (y->color != rb_tree_red) {
        // 自上向下调整
        // x这边少一个黑色节点
        while (x != root && (!x || x->color == rb_tree_black))
        {
            if (x == x_parent->left)
            {
                // x的兄弟节点
                base_ptr w = x_parent->right;
                // case 1 兄弟节点的颜色是红色
                /*
                (01) 将x的兄弟节点设为“黑色”。
                (02) 将x的父节点设为“红色”。
                (03) 对x的父节点进行左旋。
                (04) 左旋后,重新设置x的兄弟节点。
                */
                if (w->color == rb_tree_red)
                {
                    w->color = rb_tree_black;
                    x_parent->color = rb_tree_red;
                    rb_tree_rotate_left(x_parent, root);
                    w = x_parent->right;
                } // 此时x的兄弟节点已经改变, x仍然少一个黑色节点
                  //它的兄弟节点也一定是黑色节点了
                //x的兄弟节点是黑色,x的兄弟节点的两个孩子都是黑色。
                /*
                (01) 将x的兄弟节点设为“红色”。
                (02) 设置“x的父节点”为“新的x节点”
                */
                if ((!w->left || w->left->color == rb_tree_black) &&
                    (!w->right || w->right->color == rb_tree_black))
                {
                    w->color = rb_tree_red;
                    x = x_parent;
                    x_parent = x_parent->parent;
                }
                else
                {
                    // x的兄弟节点是黑色;
                    // x的兄弟节点的左孩子是红色,右孩子是黑色的。
                    /*
                    (01) 将x兄弟节点的左孩子设为“黑色”。
                    (02) 将x兄弟节点设为“红色”。
                    (03) 对x的兄弟节点进行右旋。
                    (04) 右旋后,重新设置x的兄弟节点。
                    */
                    if (!w->right || w->right->color == rb_tree_black)
                    {
                        if (w->left)
                            w->left->color = rb_tree_black;
                        w->color = rb_tree_red;
                        rb_tree_rotate_right(w, root);
                        w = x_parent->right;
                    } // 兄弟节点为黑色,右边孩子是红色
                      // x的兄弟节点是黑色;x的兄弟节点的右孩子是红色的,x的兄弟节点的左孩子任意颜色。
                    /*
                    (01) 将x父节点颜色赋值给 x的兄弟节点。
                    (02) 将x父节点设为“黑色”。
                    (03) 将x兄弟节点的右子节设为“黑色”。
                    (04) 对x的父节点进行左旋。
                    (05) 设置“x”为“根节点”。
                    */
                    w->color = x_parent->color;
                    x_parent->color = rb_tree_black;
                    if (w->right)
                        w->right->color = rb_tree_black;
                    rb_tree_rotate_left(x_parent, root);
                    break;
                }
            }
            else
            {
                base_ptr w = x_parent->left;
                if (w->color == rb_tree_red)
                {
                    w->color = rb_tree_black;
                    x_parent->color = rb_tree_red;
                    rb_tree_rotate_right(x_parent, root);
                    w = x_parent->left;
                }
                if ((!w->right || w->right->color == rb_tree_black) &&
                    (!w->left || w->left->color == rb_tree_black))
                {
                    w->color = rb_tree_red;
                    x = x_parent;
                    x_parent = x_parent->parent;
                }
                else
                {
                    if (!w->left || w->left->color == rb_tree_black)
                    {
                        if (w->right)
                            w->right->color = rb_tree_black;
                        w->color = rb_tree_red;
                        rb_tree_rotate_left(w, root);
                        w = x_parent->left;
                    }
                    w->color = x_parent->color;
                    x_parent->color = rb_tree_black;
                    if (w->left)
                        w->left->color = rb_tree_black;
                    rb_tree_rotate_right(x_parent, root);
                    break;
                }
            }
        }
        if (x)
            x->color = rb_tree_black;
    }
    return y;
}

// operator
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline bool operator==(
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &lhs, 
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &rhs) {
    return lhs.size() == rhs.size() && 
        std::equal(lhs.cbegin(), rhs.cbegin(), rhs.cend());
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline bool operator!=(
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &lhs, 
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &rhs) {
    return !(lhs == rhs);
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline bool operator<(
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &lhs, 
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &rhs) {
    return std::lexicographical_compare(
        lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline bool operator>(
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &lhs, 
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &rhs) {
    return rhs < lhs;
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline bool operator<=(
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &lhs, 
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &rhs) {
    return !(rhs < lhs);
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline bool operator>=(
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &lhs, 
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &rhs) {
        return !(lhs < rhs);
}

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline void swap(
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &lhs, 
    const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &rhs) noexcept{
    lhs.swap(rhs);
}

}

测试

IDE:vscode
项目文件格式:
CSDN图标

文件:main.cpp

#include <algorithm>
#include <functional>
#include <iostream>
#include <memory>
#include "rb_tree.h"

using namespace MiniSTL;

template <class T>
struct identity
{
    identity(){}
    const T &operator()(const T &val) {
        return val;
    }
};

using rep_type = 
        rb_tree<int, int, identity<int>, std::less<int>>;

void printTree(const rep_type &t) {
    std::cout << "顺序输出结果:" << std::endl;
    typename rep_type::const_iterator it = t.begin();
    while (it != t.end()) {
        std::cout << *it << " ";
        ++it;
    }
    std::cout << std::endl;
}

int main() {
    std::allocator<__rb_tree_node<int>> sp;
    sp.allocate(sizeof(__rb_tree_node<int>));
    
    rep_type t;
    std::cout << "插入:";
    for (int i = 0; i < 20; ++i) {
        int temp = rand() % 20;
        std::cout << temp << " ";
        t.insert_unique(temp);
    }
    std::cout << std::endl;
    printTree(t);

    std::cout << "删除:";
    for (int i = 0; i < 20; ++i) {
        int temp = rand() % 20;
        std::cout << temp << " ";
        t.erase(temp);
    }
    std::cout << std::endl;
    printTree(t);
    return 0;
}

测试结果

测试用例使用的重复节点不插入。
在这里插入图片描述

内容分析部分参考文章:
https://www.cnblogs.com/skywang12345/p/3245399.html

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值