STL源码剖析(二十一)set、heap相关算法

set算法
STL提供了四种set相关的算法<stl_algo.h>,分别是并集union,交集intersection,差集difference,对称差集symmetric difference,与数学上的意义不一样。
本节算法接受set/multiset容器作为输入区间,不接受hash_set/hash_multiset作为输入区间。
输入及输出区间都是排序区间且元素不唯一,返回迭代器指向输出区间的尾端。

set_union
set_union算法构造以S1为基础,S2与S1的并集,假设一个值在S1出现n次,在S2出现m次,那么该值在输出区间会出现max(m, n)次,其中n个来自于S1,其余来自于S2。
set_union是一种稳定操作,输入区间内元素的相对顺序不会改变,STL提供两个版本的算法,第一版本使用operator<进行元素比较,第二版本采用仿函数comp进行比较。

set_intersection
set_intersection构造以S1为基础,S2与S1的交集,假设一个值在S1出现n次,在S2出现m次,那么该值在输出区间会出现min(m, n)次,并且全部来自于S1。

set_difference
set_difference构造以S1为基础的S1-S2差集,出现在S1但不出现于S2的元素,如果某值在S1出现n次,在S2出现m次,那么该值在输出区间出现max(n-m, 0)次,并且全部来自于S1,n必须大于m,否则不出现。

set_symmetric_difference
set_symmetric_difference构造S1、S2对称差集,即(S1-S2)U(S2-S1),如果某个值在S1出现n次,在S2出现m次,该值在输出区间出现|n-m|次,如果n>m,输出区间内的n-m个元素来自S1,如果n<m,输出区间m-n个元素来自于S2。

heap算法
四个heap算法在前面heap中已介绍,make_heap(), pop_heap(), push_heap(), sort_heap(),此处不做介绍。

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
  //使用operator<比较元素
  template<typename _InputIterator1, typename _InputIterator2,
	   typename _OutputIterator>
    _OutputIterator
    set_union(_InputIterator1 __first1, _InputIterator1 __last1,
	      _InputIterator2 __first2, _InputIterator2 __last2,
	      _OutputIterator __result)
    {
      typedef typename iterator_traits<_InputIterator1>::value_type
	_ValueType1;
      typedef typename iterator_traits<_InputIterator2>::value_type
	_ValueType2;
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType1>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType2>)
      __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
      __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
      __glibcxx_requires_sorted_set(__first1, __last1, __first2);
      __glibcxx_requires_sorted_set(__first2, __last2, __first1);

      while (__first1 != __last1 && __first2 != __last2)
	{ //当两区间都未到达尾端时,执行以下操作
	  if (*__first1 < *__first2) //元素比较
	    { //将较小元素者记录于目标区间并移动迭代器,进行下次比较
	      *__result = *__first1; //记录较小元素
	      ++__first1; //移动较小元素迭代器,另一区间迭代器不动
	    }
	  else if (*__first2 < *__first1)
	    {
	      *__result = *__first2;
	      ++__first2;
	    }
	  else
	    { //两元素相等时,记录目标区间,移动两输入迭代器
	      *__result = *__first1;
	      ++__first1;
	      ++__first2;
	    }
	  ++__result; //输出区间迭代器移动
	} //输入区间有一区间到达尾端即结束循环
	  //两区间有一空白区间,将另一区间剩余元素拷贝到输出区间
      return std::copy(__first2, __last2, std::copy(__first1, __last1,
						    __result)); 
    }
  //使用仿函数__comp比较元素
  template<typename _InputIterator1, typename _InputIterator2,
	   typename _OutputIterator, typename _Compare>
    _OutputIterator
    set_union(_InputIterator1 __first1, _InputIterator1 __last1,
	      _InputIterator2 __first2, _InputIterator2 __last2,
	      _OutputIterator __result, _Compare __comp)
    {
      typedef typename iterator_traits<_InputIterator1>::value_type
	_ValueType1;
      typedef typename iterator_traits<_InputIterator2>::value_type
	_ValueType2;

      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType1>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType2>)
      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
				  _ValueType1, _ValueType2>)
      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
				  _ValueType2, _ValueType1>)
      __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
      __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);

      while (__first1 != __last1 && __first2 != __last2)
	{
	  if (__comp(*__first1, *__first2))
	    {
	      *__result = *__first1;
	      ++__first1;
	    }
	  else if (__comp(*__first2, *__first1))
	    {
	      *__result = *__first2;
	      ++__first2;
	    }
	  else
	    {
	      *__result = *__first1;
	      ++__first1;
	      ++__first2;
	    }
	  ++__result;
	}
      return std::copy(__first2, __last2, std::copy(__first1, __last1,
						    __result));
    }

  template<typename _InputIterator1, typename _InputIterator2,
	   typename _OutputIterator>
    _OutputIterator
    set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
		     _InputIterator2 __first2, _InputIterator2 __last2,
		     _OutputIterator __result)
    {
      typedef typename iterator_traits<_InputIterator1>::value_type
	_ValueType1;
      typedef typename iterator_traits<_InputIterator2>::value_type
	_ValueType2;
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType1>)
      __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
      __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
      __glibcxx_requires_sorted_set(__first1, __last1, __first2);
      __glibcxx_requires_sorted_set(__first2, __last2, __first1);
      //当两区间都未到达尾端时,执行以下操作
      while (__first1 != __last1 && __first2 != __last2)
		if (*__first1 < *__first2)
		  ++__first1;
		else if (*__first2 < *__first1)
		  ++__first2;
		else //移动输入区间迭代器直到有相等元素
		  { //记录元素于目标区间,移动输入、输出区间迭代器
		    *__result = *__first1;
		    ++__first1;
		    ++__first2;
		    ++__result;
		  }
      return __result;
    }

  template<typename _InputIterator1, typename _InputIterator2,
	   typename _OutputIterator, typename _Compare>
    _OutputIterator
    set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
		     _InputIterator2 __first2, _InputIterator2 __last2,
		     _OutputIterator __result, _Compare __comp)
    {
      typedef typename iterator_traits<_InputIterator1>::value_type
	_ValueType1;
      typedef typename iterator_traits<_InputIterator2>::value_type
	_ValueType2;

      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType1>)
      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
				  _ValueType1, _ValueType2>)
      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
				  _ValueType2, _ValueType1>)
      __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
      __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);

      while (__first1 != __last1 && __first2 != __last2)
	if (__comp(*__first1, *__first2))
	  ++__first1;
	else if (__comp(*__first2, *__first1))
	  ++__first2;
	else
	  {
	    *__result = *__first1;
	    ++__first1;
	    ++__first2;
	    ++__result;
	  }
      return __result;
    }

  template<typename _InputIterator1, typename _InputIterator2,
	   typename _OutputIterator>
    _OutputIterator
    set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
		   _InputIterator2 __first2, _InputIterator2 __last2,
		   _OutputIterator __result)
    {
      typedef typename iterator_traits<_InputIterator1>::value_type
	_ValueType1;
      typedef typename iterator_traits<_InputIterator2>::value_type
	_ValueType2;
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType1>)
      __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
      __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)	
      __glibcxx_requires_sorted_set(__first1, __last1, __first2);
      __glibcxx_requires_sorted_set(__first2, __last2, __first1);
      //当两区间都未到达尾端时,执行以下操作
      while (__first1 != __last1 && __first2 != __last2)
		if (*__first1 < *__first2)
		  { //第一区间元素小于第二区间元素,记录此值并移动迭代器
		    *__result = *__first1;
		    ++__first1; //输出区间移动
		    ++__result; //第一区间移动
		  }
		else if (*__first2 < *__first1) //第一区间元素大于第二区间元素
		  ++__first2; //第二区间移动迭代器
		else //两元素相等,S1、S2移动迭代器
		  {
		    ++__first1;
		    ++__first2;
		  }
      return std::copy(__first1, __last1, __result);
    }

  template<typename _InputIterator1, typename _InputIterator2,
	   typename _OutputIterator, typename _Compare>
    _OutputIterator
    set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
		   _InputIterator2 __first2, _InputIterator2 __last2,
		   _OutputIterator __result, _Compare __comp)
    {
      typedef typename iterator_traits<_InputIterator1>::value_type
	_ValueType1;
      typedef typename iterator_traits<_InputIterator2>::value_type
	_ValueType2;
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType1>)
      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
				  _ValueType1, _ValueType2>)
      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
				  _ValueType2, _ValueType1>)
      __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
      __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);

      while (__first1 != __last1 && __first2 != __last2)
	if (__comp(*__first1, *__first2))
	  {
	    *__result = *__first1;
	    ++__first1;
	    ++__result;
	  }
	else if (__comp(*__first2, *__first1))
	  ++__first2;
	else
	  {
	    ++__first1;
	    ++__first2;
	  }
      return std::copy(__first1, __last1, __result);
    }

  template<typename _InputIterator1, typename _InputIterator2,
	   typename _OutputIterator>
    _OutputIterator
    set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
			     _InputIterator2 __first2, _InputIterator2 __last2,
			     _OutputIterator __result)
    {
      typedef typename iterator_traits<_InputIterator1>::value_type
	_ValueType1;
      typedef typename iterator_traits<_InputIterator2>::value_type
	_ValueType2;
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType1>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType2>)
      __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
      __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)	
      __glibcxx_requires_sorted_set(__first1, __last1, __first2);
      __glibcxx_requires_sorted_set(__first2, __last2, __first1);
      //当两区间都未到达尾端时,执行以下操作
      while (__first1 != __last1 && __first2 != __last2)
	if (*__first1 < *__first2) //两元素不相等时取出该元素,移动迭代器
	  {
	    *__result = *__first1;
	    ++__first1;
	    ++__result;
	  }
	else if (*__first2 < *__first1)
	  {
	    *__result = *__first2;
	    ++__first2;
	    ++__result;
	  }
	else //两元素相等时,输入区间移动迭代器
	  {
	    ++__first1;
	    ++__first2;
	  }
      return std::copy(__first2, __last2, std::copy(__first1,
						    __last1, __result));
    }

  template<typename _InputIterator1, typename _InputIterator2,
	   typename _OutputIterator, typename _Compare>
    _OutputIterator
    set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
			     _InputIterator2 __first2, _InputIterator2 __last2,
			     _OutputIterator __result,
			     _Compare __comp)
    {
      typedef typename iterator_traits<_InputIterator1>::value_type
	_ValueType1;
      typedef typename iterator_traits<_InputIterator2>::value_type
	_ValueType2;
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType1>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
				  _ValueType2>)
      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
				  _ValueType1, _ValueType2>)
      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
				  _ValueType2, _ValueType1>)
      __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
      __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);

      while (__first1 != __last1 && __first2 != __last2)
	if (__comp(*__first1, *__first2))
	  {
	    *__result = *__first1;
	    ++__first1;
	    ++__result;
	  }
	else if (__comp(*__first2, *__first1))
	  {
	    *__result = *__first2;
	    ++__first2;
	    ++__result;
	  }
	else
	  {
	    ++__first1;
	    ++__first2;
	  }
      return std::copy(__first2, __last2, 
		       std::copy(__first1, __last1, __result));
    }

_GLIBCXX_END_NAMESPACE_ALGO
} // namespace std
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值