【数据结构】实现大小堆也叫二叉堆(类似c++中的优先队列)
2017-02-25 15:08
961 查看
二叉堆:
是一种特殊的堆,依赖于完成完全二叉树和向量实现的。分为最大堆和最小堆。
最大堆:父节点的键值总是大于或等于任何一个子节点的键值。
![](http://img.blog.csdn.net/20170225145114521)
最小堆:父节点的键值总是小于或等于任何一个子节点的键值。
![](http://img.blog.csdn.net/20170225144926440?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYTE0MTQzNDU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
存储:二叉树一般用数组来存储表示,在下面的实现中使用了STL中的vector。根节点在数组中的位置是0,第n个位置的左孩子下标为n*2+1,右孩子为2*n+2 ,当前孩子存在的前提是计算后下标要小于数组总个数。而用孩子结点的下标c,可以计算出双亲的下标(c-1)/2。
基本操作:可以进行插入结点,移除最小的结点,和返回最小的结点,返回当前堆中元素个数。
代码:这个是用模板参数实现,传入函数对象生成大小堆,默认小堆:
这个是用模板的模板参数实现:
是一种特殊的堆,依赖于完成完全二叉树和向量实现的。分为最大堆和最小堆。
最大堆:父节点的键值总是大于或等于任何一个子节点的键值。
最小堆:父节点的键值总是小于或等于任何一个子节点的键值。
存储:二叉树一般用数组来存储表示,在下面的实现中使用了STL中的vector。根节点在数组中的位置是0,第n个位置的左孩子下标为n*2+1,右孩子为2*n+2 ,当前孩子存在的前提是计算后下标要小于数组总个数。而用孩子结点的下标c,可以计算出双亲的下标(c-1)/2。
基本操作:可以进行插入结点,移除最小的结点,和返回最小的结点,返回当前堆中元素个数。
代码:这个是用模板参数实现,传入函数对象生成大小堆,默认小堆:
#ifndef _HEAP_H_ #define _HEAP_H_ #include <cassert> #include <vector> #include <iostream> using namespace std; // 仿函数小堆调用 template <class T> class Less { public: bool operator()(const T& left, const T& right) { return left <= right; } }; // 仿函数大堆调用 template <class T> class Greater { public: bool operator()(const T& left, const T& right) { return left > right; } }; // 模板参数的大小堆 template <class T, class Compare = Less<T>> class Heap { public: Heap(){} Heap(const T arr[] , int size) { for (int i=0; i<size; ++i) { _heap.push_back(arr[i]); } int last = (size - 2)/2; for (int i=last; last>=0; --last) { _AdjustDown(last, size); } } void Insert(const T data) { _heap.push_back(data); _AdjustUp(_heap.size()); } T& Top() { assert(!_heap.empty()); return _heap[0]; } const T& Top()const { assert(!_heap.empty()); return _heap[0]; } void Remove() { int size = _heap.size(); if (size > 1) { std::swap(_heap[0], _heap[size-1]); _heap.pop_back(); _AdjustDown(0, _heap.size()); } else { _heap.pop_back(); } } private: void _AdjustUp(int size) { int child = size - 1; int parent = (child-1)/2; while (child != 0) { // 孩子小于父亲 if (Compare()(_heap[child], _heap[parent])) { std::swap(_heap[child], _heap[parent]); child = parent; parent = (child - 1 )/2; } else { break; } } } void _AdjustDown(int root, int size) { int child = root*2 + 1; int parent = root; while (child < size) { if (child+1 < size && Compare()(_heap[child+1], _heap[child]) ) { child += 1; } // 小 less if (Compare()(_heap[child], _heap[parent])) { std::swap(_heap[child], _heap[parent]); parent = child; child = child *2 + 1; } else { break; } } } private: vector<T> _heap; }; #endif _HEAP_H_
这个是用模板的模板参数实现:
#ifndef _HEAP_H_ #define _HEAP_H_ #include <cassert> #include <vector> #include <iostream> using namespace std; // 仿函数小堆调用 template <class T> class Less { public: bool operator()(const T& left, const T& right) { return left <= right; } }; // 仿函数大堆调用 template <class T> class Greater { public: bool operator()(const T& left, const T& right) { return left > right; } }; // 模板的模板参数 大小堆 template<class T, template<class> class Compare = Less> class Heap { public: Heap(){} Heap(const T arr[], int size) { for (int i=0; i<size; ++i) { _heap.push_back(arr[i]); } int root = (size - 2)/2; for (int i=root; i>=0; --i) { _AdjustDown(i, size); } } void Insert(const T& data) { _heap.push_back(data); _AdjustUp(_heap.size()); } void Remove() { if (!_heap.empty()) { if (_heap.size()>1) { std::swap(_heap[0], _heap[_heap.size()-1]); _heap.pop_back(); _AdjustDown(0, _heap.size()); } else { _heap.pop_back(); } } } T& Top() { assert(!_heap.empty()); return _heap[0]; } const T& Top()const { assert(!_heap.empty()); return _heap[0]; } private: void _AdjustUp(int size) { int child = size-1; int parent= (child-1)/2; while (child != 0) { if (Compare<T>()(_heap[child], _heap[parent])) { std::swap(_heap[child], _heap[parent]); child = parent; parent = (child-1)/2; } else { break; } } } void _AdjustDown(int root, int size) { int parent = root; int child = root*2 + 1; while (child < size) { if (child+1 < size && Compare<T>()(_heap[child+1],_heap[child]) ) { child = child+1; } if (Compare<T>()(_heap[child], _heap[parent])) { std::swap(_heap[child], _heap[parent]); parent = child; child = child*2 + 1; } else { break; } } } private: vector<T> _heap; }; #endif _HEAP_H_
相关文章推荐
- 数据结构_使用二叉堆实现优先队列
- 数据结构之优先队列--二叉堆(Java实现)
- [数据结构]队列的实现-C++
- 【c++版数据结构】之循环队列的实现
- 数据结构学习之队列的链式存储的C++实现
- 数据结构队列C++实现 链式和循环
- 数据结构与算法——优先队列类的C++实现(二叉堆)
- 常用数据结构STL实现(优先队列、队列、栈)
- 算法基础:排序(四)——二叉堆、优先队列、堆排序——Python实现
- 优先队列之二叉堆(JAVA实现)
- C++数据结构 之 优先队列_Priority Queue
- 数据结构Java实现07----队列:顺序队列&顺序循环队列、链式队列、顺序优先队列
- 最小堆优先队列C++实现
- 二叉堆实现优先队列中的上滤和下滤
- 二叉堆(binary heap)—— 优先队列的实现
- 数据结构Java实现07----队列:顺序队列&顺序循环队列、链式队列、顺序优先队列
- 二叉堆实现优先队列
- 数据结构--用堆实现优先队列
- 优先队列(二叉堆实现) + 堆排序
- 数据结构_队列_用链表动态建立释放节点实现队列各种操作_C++实现