《STL源码剖析》 RB_tree insert_uniuqe()函数解析

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 != 0) {      // 从根节点开始,往下寻找适当的插入点
		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);
}

以上代码基本上是copy 《STL源码剖析》书籍的224页的代码,只是添加了一行注释, 对于 --j 的注释:

--j 的作用是 找到 (小于或等于当前节点的最大的那个节点)

这段代码的逻辑是:

  • 首先查看插入的新值是否是所有值中最小的,如果是,就插入,对应代码:
	if (comp) // 如果离开 while 循环时 comp 为真,(表示遇到“大”,将插入于左侧)
		if (j == begin())   // 如果插入点的父节点为最左节点
			return pair<iterator, bool>(__insert(x, y, v), true);
  • 其次,如果插入的新值不是所有值中最小的,就 --j ,找到小于或等于当前节点的最大的那个节点,然后判断找到的节点的键值是否小于 欲插入节点 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);

    直接返回

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值