// 安插新值;節點鍵值不允許重複,若重複則安插無效。
// 注意,傳回值是個pair,第一元素是個 RB-tree 迭代器,指向新增節點,
// 第二元素表示安插成功與否。
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)); // v 鍵值小於目前節點之鍵值?
x = comp ? left(x) : right(x); // 遇「大」則往左,遇「小於或等於」則往右
}
// 離開 while 迴圈之後,y 所指即安插點之父節點(此時的它必為葉節點) iterator j = iterator(y); // 令迭代器j指向安插點之父節點 y
if (comp) // 如果離開 while 迴圈時 comp 為真(表示遇「大」,將安插於左側)
if (j == begin()) // 如果安插點之父節點為最左節點
return pair<iterator,bool>(__insert(x, y, v), true);
// 以上,x 為安插點,y 為安插點之父節點,v 為新值。
else // 否則(安插點之父節點不為最左節點)
--j; // 調整 j,回頭準備測試...
if (key_compare(key(j.node), KeyOfValue()(v)))
// 小於新值(表示遇「小」,將安插於右側)
return pair<iterator,bool>(__insert(x, y, v), true); // 進行至此,表示新值一定與樹中鍵值重複,那麼就不該插入新值。
return pair<iterator,bool>(j, false);
}

以上iterator j的作用为:若待插入的key与某个结点相同(设为p),则在while循环中,某一次x = p后,大于等于向右走,则下一次x =
p.right,由于v的值一定小于p的右子树中任何一个值,所以进入p的右子树后,x一定是一直向左走直到节点y(y的左儿子为空)。则y为p的右子树最小值,iterator(p)
= iterator(y) - 1,p即为代码中的j。若v与j的值不同,则可以执行插入操作,否则返回j和false。

http://blog.csdn.net/ww32zz/article/details/48523759

comp == true 时,如果 j != begin() 则 --j,此时 j 指向 y 的前一个节点,这个节点可能和新插入的节点 v 的值相同,也就是上面说的 p,所以需要再比较 p 和 v

comp == false 时,y 的 right 为 0,v >= y , 如果 y 是最后一个节点,即 end() - 1,再判断是否 y < v;如果 y 不是最后一个节点,y的后一个节点是 y 的父节点或更上层的节点,

而且 y 在 y后一节点的 left tree 中,v 一定小于 y的后一个节点,否则不会到达 y。所以程序中没有判断 y 是否是最后一个节点。

这里两种情况的不对称根源于比较函数 < 和 >= 的不对称。

最新文章

  1. Android 手机卫士--参照文档编写选择器
  2. 写在分类之首-----to do list!
  3. 【CodeForces 697C】Lorenzo Von Matterhorn(LCA)
  4. wget的使用详解
  5. 使用jmx监控tomcat
  6. Android生命周期和Service生命周期
  7. 解决:HotSeat短信图标提醒有误
  8. 2016 Multi-University Training Contest 5 Two
  9. Java Day 10
  10. 说明&amp;总目录
  11. WPF 进程间通讯----inter-process communication
  12. iOS开发——语法篇OC篇&amp;静态方法与实例方法
  13. centos打开3306端口
  14. Core Data使用之一(Swift): 保存
  15. python接口自动化(九)--python中字典和json的区别(详解)
  16. ubuntu系统安装mysql登陆提示 解决Mysql ERROR 1045 (28000): Access denied for user &#39;root&#39;@&#39;localhost&#39;问题
  17. java进程占用系统内存高,排查解决
  18. django会话session
  19. spark wordcont Spark: sortBy和sortByKey函数详解
  20. fopen flock fclose 文件用法

热门文章

  1. 配置管理 ACM 在高可用服务 AHAS 流控降级组件中的应用场景
  2. bzoj 3598 [Scoi2014]方伯伯的商场之旅——数位dp
  3. 转:国内从事CV相关的企业
  4. 如何写JavaScript中的callback回调函数
  5. pl/sql进阶一控制结构
  6. beanstalkd 启动跟停止
  7. 快速启动Oracle服务
  8. oralce基本select语句
  9. 提供SaaS Launchkit,快速定制,一云多端等能力,一云多端将通过小程序云实现
  10. Docker镜像部分详解