is_heap和is_heap_until 用法与源码剖析

一:用法示例

is_heap一共两个重载:

default (1)
template <class RandomAccessIterator>
  bool is_heap ( RandomAccessIterator first ,  RandomAccessIterator last ) ;
custom (2)   
template <class RandomAccessIterator, class Compare>
  bool is_heap ( RandomAccessIterator first ,  RandomAccessIterator last , Compare comp ) ;

返回值bool型,功能是判断在[ first , last )范围的数是否能构成一个堆。根据第三参数comp确定是大顶堆还是小顶堆,默认是大顶堆。

如不理解堆的概念,建议先学习“堆排序“这个排序算法,具体内容请读者自行百度。

例子:

#include<iostream>
#include<functional>
#include<algorithm>
#include<vector>

using namespace std;

int main()
{
	
	int a[10] = { 2,1,6,4,9,10,3,5,8,7 };
	vector<int> v(a, a + 10);

	if (!is_heap(v.begin(), v.end()))
		cout << "not heap!\n";//不是一个堆

	sort(v.begin(), v.end());

	if (!is_heap(v.begin(), v.end()))
		cout << "not max_heap!\n";//不是一个大顶堆

	if (is_heap(v.begin(), v.end(),greater<>()))
		cout << "is min_heap!\n";//是小顶堆

	return 0;
}

运行如图:



is_heap_until也是两个重载:

default (1)   

template <class RandomAccessIterator>
  RandomAccessIterator is_heap_until ( RandomAccessIterator first , RandomAccessIterator last ) ;
custom (2)   
template <class RandomAccessIterator ,  class Compare>
  RandomAccessIterator is_heap_until ( RandomAccessIterator first , RandomAccessIterator last , Compare comp ) ;

返回值是一个迭代器,指向第一个不满足堆元素(Returns an iterator to the first element in the range [first,last) which is not in a valid position if the range is considered a heap (as if constructed with make_heap).)。

例子:

#include<iostream>
#include<functional>
#include<algorithm>
#include<vector>

using namespace std;

int main()
{
	
	int a[10] = { 2,1,6,4,9,10,3,5,8,7 };
	vector<int> v(a, a + 10);
	sort(v.begin(), v.end());//现在是一个小顶堆

	v[3] = 20;//现在既不是大顶堆也不是小顶堆

	auto it1 = is_heap_until(v.begin(), v.end(), less<>());
	auto it2 = is_heap_until(v.begin(), v.end(), greater<>());

	cout << "前" << it1 - v.begin() << "个元素满足大顶堆!\n";
	cout << "前" << it2 - v.begin() << "个元素满足小顶堆!\n";

	return 0;
}

运行如图:



二:源码剖析

is_heap和is_heap_until的源码实现都是依赖is_heap_until,也就是下面源码的第一个模板函数。

// TEMPLATE FUNCTIONS is_heap AND is_heap_until WITH PRED
template<class _RanIt,
	class _Diff,
	class _Pr> inline
	_RanIt _Is_heap_until(_RanIt _First, _RanIt _Last, _Pr _Pred, _Diff *)
	{	// find extent of range that is a heap ordered by _Pred
	_Diff _Size = _Last - _First;

	if (2 <= _Size)//如果只有一个元素的话肯定满足堆
		for (_Diff _Off = 0; ++_Off < _Size; )
			if (_DEBUG_LT_PRED(_Pred, *(_First + (_Off - 1) / 2),*(_First + _Off)))//相当于if(_Pred(*(_First + (_Off - 1) / 2),*(_First + _Off)))
				return (_First + _Off);
	return (_Last);
	}

template<class _RanIt,
	class _Pr>
	_RanIt is_heap_until(_RanIt _First, _RanIt _Last, _Pr _Pred)
	{	// find extent of range that is a heap ordered by _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER_IF(2 <= _Last - _First, _Pred);
	return (_Rechecked(_First,
		_Is_heap_until(_Unchecked(_First), _Unchecked(_Last), _Pred,
			_Dist_type(_First))));
	}

template<class _RanIt,
	class _Pr>
	bool is_heap(_RanIt _First, _RanIt _Last, _Pr _Pred)
	{	// test if range is a heap ordered by _Pred
	return (_STD is_heap_until(_First, _Last, _Pred) == _Last);
	}

		// TEMPLATE FUNCTIONS is_heap AND is_heap_until
template<class _RanIt>
	_RanIt is_heap_until(_RanIt _First, _RanIt _Last)
	{	// find extent of range that is a heap ordered by operator<
	return (_STD is_heap_until(_First, _Last, less<>()));
	}

template<class _RanIt>
	bool is_heap(_RanIt _First, _RanIt _Last)
	{	// test if range is a heap ordered by operator<
	return (_STD is_heap(_First, _Last, less<>()));
	}

源码摘抄自Visual Studio 2015安装目录algorithm文件中。



点击进入目录----> C++源码剖析目录





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值