码迷,mamicode.com
首页 > 其他好文 > 详细

STL最小堆

时间:2015-04-11 14:31:56      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:

前几天同学参加腾讯实习的网络笔试,闲聊中得知一道编程题目,最近也在看算法,觉得刚好用来练手。

这题觉得以最小堆实现比较方便,在C++中,以<algorithm>中 make_heap(), push_heap(), pop_heap(), sort_heap()四个函数管理堆十分方便。

make_heap(RandomIt first, RandomIt last, Compare comp)对 [first, last - 1]中的元素建立最大堆,修改comp可以处理最小堆;

push_heap(RandomIt first, RandomIt last, Compare comp)默认[first, last - 2]中元素是comp意义下的最大堆,将last - 1中的元素插入到合适的位置,使[first, last - 1]保持comp意义下的最大堆;

pop_heap(RandomIt first, RandomIt last, Compare comp)交换first 和 last - 1,并调整元素保持[first, last - 2]为comp意义下的最大堆;

 

具体题目记不得了,大致是:输入N个非负整数,每次输入一个数后,检测当前未输出的数字,若所有比它小的数字均已输出,则输出该数字,每次输出独占一行。

                                    输入完N个数字后,将剩余的数字从小到大输出。

                         举个例子:

                                     设N = 10, 输入 0 3 5 1 2 6 4 8 9 7

                                                     输出  0

                                                            1

                                                            2 3

                                                            4 5 6

                                                            7 8 9

                                                     输入 1 3 0 2 6 4 13 10 9 8

                                                     输出  0 1

                                                             2 3

                                                             4

                                                             6 8 9 10 

程序思路,设置count计数,记录输入数字的个数,mark标记下一个可以输出的数,初始 mark = 0,维护一个最小堆heap,每输入一个数num, 把它放入堆中,检测堆中最小数是否等于mark,相等则从堆中删除最小数并输出,mark++,继续检测;不等则输出换行,继续接收下一个输入。

 

C++代码:

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

#define N 10

using namespace std;

int main(void)
{
	vector<int> heap;
	int count = 0, mark  = 0, flag = 0;
	int num;
	
	make_heap(heap.begin(), heap.end(), greater<int>());
	
	while (count < N)
	{
		cin >> num;
		heap.push_back(num);
		count++;
		push_heap(heap.begin(), heap.end(), greater<int>());
		while (heap.size() != 0 && heap.front() == mark)
		{
			pop_heap(heap.begin(), heap.end(), greater<int>());
			cout << heap.back() << ‘ ‘;
			heap.pop_back();
			mark++;
			flag = 1;
		}
		if (flag)
		{
			cout << endl;
			flag = 0;
		}
	}
	//print the rest of numbers
	sort_heap(heap.begin(), heap.end(), greater<int>());
	for (vector<int>::iterator i = heap.end() - 1; i > heap.begin(); i--)
		cout << *i << ‘ ‘;
	cout << heap.front() << endl;
	
	return 0;
}

make_heap(), push_heap(), pop_heap()用于维护最大堆

比较器greater<T> 在<functional>中定义,可以使以上三个函数处理最小堆

值得注意sort_heap()函数接收一个最大堆,然后将其中元素升序排序,所以,处理最小堆时需指定greater<>,否则会有invalid heap的错误

由于加入了greater<>,排序结果是降序的,则需要逆序输出vector中的元素,一个简单的代码是

for (vector<int>::iterator i = heap.end() - 1; i >= heap.begin(); i--)
		cout << *i << ‘ ‘;
cout << endl;

但是这样在最后跳出循环时,当 i == heap.begin() 时会继续执行一次 i--,VS2013中默认提示vertor iterator not decrementable,应该是一个安全检测,所以采用如上的一个不是很和谐的方式逆序输出vector中的元素。

 

参考:http://www.tuicool.com/articles/z6326f

        http://en.cppreference.com

STL最小堆

标签:

原文地址:http://www.cnblogs.com/wertyd/p/4412922.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!