您的位置:首页 > 其它

STL 堆排序

2015-08-22 00:57 211 查看
C++ STL中提供了不少和排序相关的算法,包括堆排序(heap_sort)、排序(sort)、稳定排序(stable_sort)、局部排序(partial_sort),时间复杂度均为O(nlogn)。其中,对于堆排序,也提供了不少函数,像入堆push_heap、创建堆make_heap、出堆pop_heap,是否为堆is_heap等。首先要明确数据结构上堆的概念。对于一个迭代器区间上的元素,不管实际的数据结构如何,都可以逻辑上排成一个完全二叉树,如果树的每个父节点都不小于左右两个子节点,那么区间元素就构成了一个堆。例子很简单,算是科普性的。。。

入堆push_heap

入堆push_heap算法带有二元谓词判断comp,可以自行设定元素的大于或者小于关系,从而进一步确定创建的是大根堆还是小根堆。其函数原型对应两种,

template <class RandomAccessIterator>
  void push_heap (RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class Compare>
  void push_heap (RandomAccessIterator first, RandomAccessIterator last,
                   Compare comp);


第一种方式默认创建的是大根堆。

Given a heap in the range [first,last-1),this function extends the range considered a heap to [first,last) by placingthe value in (last-1) into its corresponding location within it.

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void print(int x)
{
	cout<<x<<" ";
}
int main()
{
	vector<int> v;
	v.push_back(38);
	v.push_back(11);
	v.push_back(15);
	v.push_back(39);
	v.push_back(60);
	v.push_back(55);
	v.push_back(20);
	v.push_back(26);
	make_heap(v.begin(),v.end());
	for_each(v.begin(),v.end(),print);
	cout<<endl;
	return 0;
}

创建堆make_heap

创建堆make_heap算法重新排列元素,使元素在逻辑上构成一个堆,默认是大根堆。函数原型有两种:

template <class RandomAccessIterator>
  void make_heap (RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class Compare>
  void make_heap (RandomAccessIterator first, RandomAccessIterator last,
                  Compare comp );




Rearranges the elements in the range[first,last) in such a way that they form a heap.

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void print(int x)
{
	cout<<x<<" ";
}
int main()
{
	vector<int> v;
	v.push_back(38);
	v.push_back(11);
	v.push_back(15);
	v.push_back(39);
	v.push_back(60);
	v.push_back(55);
	v.push_back(20);
	v.push_back(26);
	make_heap(v.begin(),v.end());
	for_each(v.begin(),v.end(),print);
	cout<<endl;
	return 0;
}



出堆pop_heap

相对于push_heap,pop_heap将元素进行出堆操作。

实现过程大概是这样的,将已经够成堆的迭代器区间中的最大值元素即根节点,移动到最后元素位置,原来的最后元素调整为根节点后,再对区间元素重新创建堆。

函数原型有两个:



template <class RandomAccessIterator>
  void push_heap (RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
  void push_heap (RandomAccessIterator first, RandomAccessIterator last,
                   Compare comp);




#include<iostream>
#include<algorithm>
using namespace std;
void print(int x)
{
	cout<<x<<" ";
}
int main()
{
	int iArray[]={1,2,3,4,5};
	const int len=sizeof(iArray)/sizeof(int);
	cout<<"创建堆"<<endl;
	make_heap(iArray,iArray+len);
	for_each(iArray,iArray+len,print);//5 4 3 2 1
	cout<<endl;
	cout<<"出堆一次"<<endl;
	pop_heap(iArray,iArray+len);
	for_each(iArray,iArray+len,print);//4 3 2 1 5
	return 0;
}




堆排序sort_heap

利用堆进行排序,时间复杂度为O(nlogn)。



#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

void print(int x){
	cout << x << ' ';
}

int main(void){
	vector<int> v;
	v.push_back(3);
	v.push_back(9);
	v.push_back(6);
	v.push_back(3);
	v.push_back(12);
	v.push_back(17);
	v.push_back(20);
	for_each(v.begin(), v.end(), print); cout << endl;
	//建立堆
	make_heap(v.begin(), v.end());
	cout<<"创建堆,未排序之前"<<endl; 
	for_each(v.begin(),v.end(),print);
	cout<<endl;
	//堆排序
	cout << "进行堆排序" << endl;
	sort_heap(v.begin(), v.end());
	for_each(v.begin(), v.end(), print); cout << endl;
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: