• headfirst redblack trees 由浅入深红黑树




    1、二分查找与二叉树:效率、空间、灵活性的权衡
    数据与链表的互补:
    数组: 查找快(使用二分叉找)->log2N 。插入和删除极为不便。->移动其它数据的开销。要保持数据有序,则必然有大量的插入删除操作。
    链表: 为每个元素带上两个指针,分别指向其前结点和后结点。
        1)打破了数据对空间相关性的依赖。避免了插入删除时移动数据的开销。
         2)不能使用二分查找。
    为了能在链表中使用二分叉找,我们将元素的指针做一些改变:不再指向其前后元素。而指向其二分结点元素。

    其数据结构定义如下:

    template <class Entry>
    struct Binary_node
    {
        Entry data;
        Binary_node
    <Entry> *left;
        Binary_node
    <Entry> *right;
    }
    插入和删除引起了二叉树的不平衡。

    我们将数组的范围扩大到  1-24,而且经过删除操作,只剩下了如下图的7个元素:


    任何的不平衡,可以通过两种旋转操作来完成:左旋转、右旋转。
    调整三个结点的关系: 孙子结点、父结点、爷爷结点。
    修改三个指针值:指向爷爷结点的指针(当前根结点)、指向父结点的指针、指向叔父结点的指针。


    template <class Record>
    Error_code Search_tree
    <Record> :: rotate_right( Binary_node<Record> * &current )
    {
        Binary_node
    <Record>* reg = current->left;
        current
    ->left = reg->right;
        reg
    ->right = current;
        
    // 正确地指向当前根结点
        current = reg;
        
    return okay;
    }

    template 
    <class Record>
    RB_code Search_tree
    <Record> :: rotate_left(Binary_node<Record> * &current )
    {
        Binary_node
    <Record>* reg = current->right;
        current
    ->right = reg->left;
        reg
    ->left = current;
        
    // 正确地指向当前根结点
        current = reg;
        
    return okay;
    }


    Error_code Search_tree<Record> ::double_rotate_left(Binary_node<Record> * &current )
    {
        rotate_right( current );    
        rotate_left( current );
        
    return okay;
    }
    template 
    <class Record>
    Error_code Search_tree
    <Record> :: double_rotate_right(Binary_node<Record> * &current )
    {
        rotate_left( current );
        rotate_right( current );
        
    return okay;
    }

    红黑树--懒汉平衡
    红黑树 vs 平衡二叉树
    1)性能几乎没有下降
    2)减少了开销
    基本思想:从根结点开始,层与层红黑相间。直有两层黑的相遇,才旋转。
    红黑树的基本操作:
    1)着色:flip_color()
    2) 旋转:借用  search-tree 的方法。
    红黑树结点的四种状态:
    enum RB_code { okay, red_node, left_red, right_red };
    okey: 合法的红黑树。
     red_node: 树结构平衡,根结点颜色为红。
    left_red:  树结构不平衡,左子结点为红。
    right_red:树结构不平衡,右子结点为红。
    红黑树的叶子结点:概念上存在而物理上不存在。
    最坏情况:
    插入操作:
    删除操作:
    应用:
    多数应用中,结点还包含一个父结点:
    //  Linux-2.6.17/include/linux/rbtree.h

    struct rb_node
    {
        unsigned 
    long  rb_parent_color;
    #define RB_RED          0
    #define RB_BLACK        1
        
    struct rb_node *rb_right;
        
    struct rb_node *rb_left;
    } __attribute__((aligned(
    sizeof(long))));
        
    /* The alignment might seem pointless, but allegedly CRIS needs it */

    // stl/stl_tree.h

    struct _Rb_tree_node_base
    {
      typedef _Rb_tree_Color_type _Color_type;
      typedef _Rb_tree_node_base
    * _Base_ptr;

      _Color_type _M_color; 
      _Base_ptr _M_parent;
      _Base_ptr _M_left;
      _Base_ptr _M_right;
    };
    template 
    <class _Value>
    struct _Rb_tree_node : public _Rb_tree_node_base
    {
      typedef _Rb_tree_node
    <_Value>* _Link_type;
      _Value _M_value_field;
    };
    fdfd


    Referance《data_structures and program design in cpp》
  • 相关阅读:
    Spring Boot中只能有一个WebMvcConfigurationSupport配置类
    【原创】(六)Linux进程调度-实时调度器
    【原创】(二)Linux进程调度器-CPU负载
    【原创】(十二)Linux内存管理之vmap与vmalloc
    【原创】(十一)Linux内存管理slub分配器
    【原创】(七)Linux内存管理
    【原创】(五)Linux内存管理zone_sizes_init
    【原创】(三)Linux paging_init解析
    【原创】(二)Linux物理内存初始化
    【原创】(一)ARMv8 MMU及Linux页表映射
  • 原文地址:https://www.cnblogs.com/diylab/p/1561242.html
Copyright © 2020-2023  润新知