标签:
前几天同学参加腾讯实习的网络笔试,闲聊中得知一道编程题目,最近也在看算法,觉得刚好用来练手。
这题觉得以最小堆实现比较方便,在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://www.cnblogs.com/wertyd/p/4412922.html