//---------------------------15/03/22----------------------------

//一直好奇KeyOfValue是什么,查了下就是一个和仿函数差不多的东西,在第7章会详细介绍

//现在只知道KeyOfValue()可以构造一个类调用他的operator()可以得到一个value的key

//允许重复的插入

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& v)

{

link_type y = header;

link_type x = root();

//从根节点开始搜索直到x为叶子节点

while ( x !=
)

{

y = x;

x = key_compare(KeyOfValue()(v),key(x)) ? left(x) : right(x);

}

//把一个值为v的节点插入x的位置,y是x的父节点

return __insert(x,y,v);

}

//不允许重复

//可以插入(没有重复)返回的bool为true,否则为false

template<class Key,class Value,
class KeyOfValue,class Compare,
class Alloc>

pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator,bool>

rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique(const Value& v)

{

link_type y = header;

link_type x =root();

bool comp =
true;

while( x !=
)

{

y = x;

comp = key_compare(KeyOfValue()(v),key(x));

x = comp ? left(x) :right(x);

}

iterator j = iterator(y);

//最后如果v "小于"(假设比较操作是小于) y

//这边做这样的操作是因为"大于等于"的时候都会向右走,所以需要换一下j.node和v的位置

//看看是否不相等

if(comp)

if(j == begin())   
//如果插入点的父节点是最左边的节点

return pair<iterator,bool>(__insert(x,y,v),true);

else           
//不是最左边就要--j继续判断

--j;

//这是因为只有最左边可以确定没有比v小的元素了

//如果j.node确实小于v就可以插入。

if(key_compare(key(j.node),KeyOfValue()(v)))

return pair<iterator,bool>(__insert(x,y,v),true);

return pair<iterator,bool>(j,false);

/*

总结下:会出现想等的情况只有有向右走的情况

如果最后是向右走的,那么有可能相等的元素就是j也就是y也就是要插入位置
的父节点

如果最后是向左走的,那么有可能相等的就是比j小的最大的那个元素,也就是--j

*/

}

//__insert

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)

{

link_type x = (link_type) x_;

link_type y = (link_type) y_;

link_type z;

//如果要插入的是根节点或者
要插入的位置不是空(header的左右儿子) 或v小于y 那么就是要插入到左边

if(y == header || x !=
|| key_compare(KeyOfValue()(v),key(y)))

{

z = create_node(v);

left(y) = z;   //如果y是header那可以设置leftmost为z

//如果要插入的是根节点,

if(y == header)

{

//设置根节点

root() = z;

//设置最右边的元素

rightmost() = z;

}

//如果要插到最左边

else
if(y == leftmost())

leftmost() = z;

}

else

{

z = create_node(v);

right(y) = z;

if (y == rightmost())

rightmost() = z;

}

//父节点为y左右儿子都是
空。

parent(z) = y;

left(z) =;

right(z) =;

//调整平衡

__rb_tree_rebalance(z,header->parent);

++node_count;

return iterator(z);

}

//旋转以及变色

//平衡这里inline是什么意思?里面明明有循环
而且代码这么长

//下面的代码几乎和算法导论里的一样

inline
void

__rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root)

{

x->color = __rb_tree_red;

while(x != root && x->parent->color == __rb_tree_red)

{

if(x->parent == x->parent->parent->left)

{

__rb_tree_node_base* y =x->parent->parent->right;

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

{

if(x == x->parent->right)

{

x = x->parent;

__rb_tree_rotate_left(x, root);

}

x->parent->color = __rb_tree_black;

x->parent->parent->color = __rb_tree_red;

__rb_tree_rotate_right(x->parent->parent, root);

}

}

else

{

__rb_tree_node_base* y =x->parent->parent->left;

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

{

if(x == x->parent->left)

{

x = x->parent;

__rb_tree_rotate_right(x,root);

}

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;

}

//左转

inline voide

__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 !=
)

y->left->parent = x;

y->parent = x->parent;

if(x == root)

root = y;

else
if (x == x->parent->left)

x->parent->left = y;

else

x->parent->right = y;

y->left = x;

y->parent = y;

}

//右转

inline voide

__rb_tree_rotate_right(__rb_tree_node_base* x,__rb_tree_node_base*& root)

{

__rb_tree_node_base* y = x->left;

x->left = y->right;

if(y->right !=
)

y->right->parent = x;

y->parent = x->parent;

if(x == root)

root = y;

else
if (x == x->parent->right)

x->parent->right = y;

else

x->parent->left = y;

y->right= x;

y->parent = y;

}

//find

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& k)

{

link_type y =header;

link_type x =root();

while(x !=
)

if(!key_compare(key(x), k))

y = x, x =left(x);

else

x = right(x);

iterator j =iterator(y);

return (j ==end() || key_compare(k, key(j.node))) ? end() :j;

}

//最后没有delete操作,之前的算法导论部分已经给出了delete操作


stl源码剖析 详细学习笔记 RB_tree (2)的更多相关文章

  1. stl源码剖析 详细学习笔记 RB_tree (1)

    // //  RB_tree_STL.cpp //  笔记 // //  Created by fam on 15/3/21. // // #include "RB_tree_STL.h&q ...

  2. stl源码剖析 详细学习笔记 set map

    // //  set map.cpp //  笔记 // //  Created by fam on 15/3/23. // // //---------------------------15/03 ...

  3. stl源码剖析 详细学习笔记 hashtable

    //---------------------------15/03/24---------------------------- //hashtable { /* 概述: sgi采用的是开链法完成h ...

  4. stl源码剖析 详细学习笔记heap

    // //  heap.cpp //  笔记 // //  Created by fam on 15/3/15. // // //---------------------------15/03/15 ...

  5. stl源码剖析 详细学习笔记 空间配置器

    //---------------------------15/04/05---------------------------- /* 空间配置器概述: 1:new操作包含两个阶段操作 1>调 ...

  6. stl源码剖析 详细学习笔记 算法(1)

    //---------------------------15/03/27---------------------------- //算法 { /* 质变算法:会改变操作对象之值 所有的stl算法都 ...

  7. stl源码剖析 详细学习笔记 算法总览

    //****************************基本算法***************************** /* stl算法总览,不在stl标准规格的sgi专属算法,都以 *加以标 ...

  8. stl源码剖析 详细学习笔记 hashset hashmap

    //---------------------------15/03/26---------------------------- //hash_set { /* hash_set概述: 1:这是一个 ...

  9. stl源码剖析 详细学习笔记priority_queue slist

    // //  priority_queue.cpp //  笔记 // //  Created by fam on 15/3/16. // // //------------------------- ...

随机推荐

  1. 关于MSCOMM.OCX无法正常注册的问题解决

    [问题] 关于“Component'MSCOMM32.OCX'or one of its dependencies not correctly registered: afole is missing ...

  2. KB和KiB的区别

    差别是KB等单位以10为底数的指数,KiB是以2为底数的指数. K 与 Ki 分别表示 kilo-(千) 与 kibi-(二进制千) .作为前缀使用时, k 表示 1,000,Ki 表示1,024. ...

  3. python基础学习9----深浅拷贝

    数据类型有可变类型和不可变类型 不可变类型:整型,长整型,浮点数,复数,布尔,字符串,元组 可变类型:列表,字典 浅拷贝 简单说只对第一层进行拷贝,如下对于列表中的列表的数据进行改变,list1和li ...

  4. 【转】Linxu学习---top实践

    [原文]https://www.toutiao.com/i6591053058258502147/ 在实际开发中,有时候会收到一些服务的监控报警,比如CPU飙高,内存飙高等,这个时候,我们会登录到服务 ...

  5. Jar版本:java.lang.UnsupportedClassVersionError: ******

    错误原因编译Java和运行Java所使用的Java的版本不一致导致:解决办法修改运行环境的Java版本或者修改编译环境的Java版本,让两者保持一致即可: java.lang.UnsupportedC ...

  6. FreeChart柱状图中如何取消柱子的倒影

    JFreeChart柱状图中如何取消柱子的倒影,让柱子显示为一个平面图 Render 该怎么设置呢? 问题补充:已解决 intervalBarRender.setShadowVisible(false ...

  7. A “Type Erasure” Pattern that Works in Swift:类型域的转换

    新视角:通过函数式编程的范畴理论来看待这个问题会更容易理解: 在低层类型无法很好表达的类型,可以将其转化为高阶类型进行表示. 将协议的实现类型转化为monad类型: 解决将具有关联类型的协议当作类型的 ...

  8. intellij IDEA软件java项目No SDK配置jdk开发,安装IDEA软件步骤

    我们在使用intellij idea开发java项目的时候,我们在创建的时候会发现提示No SDK,影响创建和使用项目,我们需要下载和配置需要的JDK 电脑 1我们使用intellij idea创建j ...

  9. 【转】 [置顶] Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它)

    在Android的应用层中,涉及到很多应用框架,例如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架,通知机制,ActionBar框架等等. ...

  10. 2、Pyspider使用入门

    1.接上一篇,在webui页面,点击右侧[Create]按钮,创建爬虫任务 2.输入[Project Name],[Start Urls]为爬取的起始地址,可以先不输入,点击[Create]进入: 3 ...