C++源码学习与解析------next_permutation

直接上源码

template<typename _BidirectionalIterator, typename _Compare>
    bool
    __next_permutation(_BidirectionalIterator __first,
		       _BidirectionalIterator __last, _Compare __comp)
    {
      if (__first == __last)     //没有元素,return false
	return false;
      _BidirectionalIterator __i = __first;
      ++__i;
      if (__i == __last)	    //只有一个元素,不排列,return false
	return false;
      __i = __last;               
      --__i;  				  //__i 指向最后一个元素

      for(;;)
	{
	  _BidirectionalIterator __ii = __i; 
	  --__i;							//从后往前遍历
	  if (__comp(__i, __ii))	//这里__comp函数以小于为例,直到找到一个a[i]<a[i+1]为止
	    {
	      _BidirectionalIterator __j = __last;
	      while (!__comp(__i, --__j)) //因为__i后面的序列一定是递减的,所以找到最小的大于__i指向的元素 交换即可
		{}
	      std::iter_swap(__i, __j);
	      std::__reverse(__ii, __last,
			     std::__iterator_category(__first)); 
			     //同时,因为__i后的元素一定是递减的(不论交换前后) 故直接逆序即可,这也就得到了比当前序列大的最小排列
	      return true;
	    }
	  if (__i == __first)     //若没找到a[i]<a[i+1] ,则此时表示已经到达了
	    {
	      std::__reverse(__first, __last,
			     std::__iterator_category(__first));
	      return false;
	    }
	}
    }

从源码中可以看出(没贴出),next_permutation的算法实现是基于__next_permutation实现的 故本文暂时只对该函数的实现进行解析。

需要注意的是,__first的实参是第一个元素,__second的实参是尾元素的后一位。

理解过程可以参看我加的注释

看源码是可以很快速地提升C++水平和算法能力的

总结全排列的算法思路就是:给定的某个排列,我们要找到比它大的最小排列。我们可以从后往前遍历该排列,找到第一个可以使当前排列变大的位置。然后再讲剩余部分,按从小到大排序即可。但是后面的序列一定是逆序的,故我们无需排序,直接reverse即可,时间复杂度可以优化到线性。

这个系列会不断更新,学习并解析c++源码,共同进步。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值