最大堆(最小堆)C++实现源码
2017-04-24 17:16
477 查看
写在前面
最近渐渐爱上写博客,觉得每天学到的知识需要保鲜,写的源码也能及时与大家分享,接下来进入正题。最大堆(最小堆)
最大堆(最小堆)是非常重要的数据结构,公司面试时经常会被问到,在这里,我不会详细介绍它的原理,而是介绍它的适用场景以及两种写法,对原理不了解的可以查看:https://en.wikipedia.org/wiki/Heap_%28data_structure%29
假设有10万个数,让你求最小的k个数,你会怎么做?
先排序,然后取前k个数,时间复杂度O(nlogn)
维护k个数的最大堆,时间复杂度O(nlogk)
考虑第一种方式,当内存有限时,没法一次载入10万个数,排序不可取,而第二种方式,每次只载入一个数,最多存储k个数(最大堆),当堆满时,通过比较当前数与堆顶值,若堆顶值大,则删除堆顶,插入当前数,反之,则不做任何操作,也就是说,最大堆一直存储着当前载入数里最小的k个数。
最大堆C++实现源码
这里给出了两种写法,最小堆同理,值得注意的是,最大堆(最小堆)一定是一颗完全二叉树,可以用数组表示,如有错误还望指正。非递归写法
#include <vector> #include <cassert> using namespace std; class MaxHeap { private: vector<int> heap; int size; public: void make_heap(vector<int>& nums, int s) { //构建堆 heap.assign(nums.begin(), nums.end()); size = s; for (int i = size / 2 - 1; i >= 0; i--) down(i); } void push(int num) { //插入元素 heap.push_back(num); size++; up(size - 1); } int pop() { //删除元素 assert(size > 0); int result = heap[0]; heap[0] = heap[size - 1]; heap.pop_back(); size--; down(0); return result; } void down(int index) { assert(index >= 0); int temp = heap[index]; index = index * 2 + 1; while (index < size) { if (index + 1 < size && heap[index] < heap[index + 1]) index++; if (heap[index] < temp) break; else { heap[(index - 1) / 2] = heap[index]; index = index * 2 + 1; } } heap[(index - 1) / 2] = temp; } void up(int index) { assert(index < size); int temp = heap[index]; while (index > 0 && temp > heap[(index - 1) / 2]) { heap[index] = heap[(index - 1) / 2]; index = (index - 1) / 2; } heap[index] = temp; } };
递归写法
void down(int index) { assert(index >= 0); int temp = index; index = index * 2 + 1; if (index >= size) return; if (index + 1 < size && heap[index] < heap[index + 1]) index++; if (heap[index] < heap[temp]) return; else { swap(heap[index], heap[temp]); down(index); } } void up(int index) { assert(index < size); if (index == 0) return; if (heap[index] < heap[(index - 1) / 2]) return; else { swap(heap[index], heap[(index - 1) / 2]); up((index - 1) / 2); } }
很明显,递归写法两元素交换次数比非递归写法多。
相关文章推荐
- 最大流—最小割的C++实现
- 最大堆、最小堆C++实现
- 最大流与最小割C++实现2——深度优先搜索
- 求最大最小元 C++实现 分治法
- c++/java/python priority_que实现最大堆和最小堆
- C++实现的带最大最小线程数的线程池(基于ACE)
- 用C++实现最小公倍数和最大公约数
- C++使用两个栈实现一个可以获取栈中最大值和最小值的栈
- C++利用vector容器实现最大最小元问题
- C++ 实现从0~100中随机生成50个数,统计出现的数字最大值和最小值,输出出现最多的次数及对应的数字
- 【C++基本功补习】查找三个数据中的最大值、最小值、中间值,两种实现方案比较
- C++实现的带最大最小线程数的线程池(基于ACE)
- [C++ 实现最大值优先队列和最小值优先队列]
- 环行缓冲区实现(V0.3) C++源码
- “基于关键字匹配的文本过滤系统”配置文件的设计和实现(C/C++源码)
- 实现窗体的最大最小关闭效果
- 自动打开“我的电脑“ C++源码实现
- “基于关键字匹配的文本过滤系统”配置文件的设计和实现(C/C++源码)
- Contourlet变换的C++源码的实现
- css实现ie6下最大,最小宽/高度