堆
堆:
堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构。
堆结构的二叉树存储是
最大堆:每个父节点的都大于孩子节点。
最小堆:每个父节点的都小于孩子节点。
template<class T> struct MaxHeap { bool operator ()(T data1, T data2) { return data1 > data2; } }; template<class T> struct MinHeap { bool operator ()(T data1, T data2) { return data1 < data2; } }; template<class T1,template<class>class T2> class Heap //堆的结构 { public: Heap(const T1* _arr,size_t size) //构造函数 { for (int i = 0; i < size; ++i) { _array.push_back(_arr[i]); } for (int i = (size - 2) / 2; i>=0; --i) { _AdjustDown(i); } }
/*从最后一个非叶节点开始调整,调整过程如下:*/
public: void _AdjustDown(size_t index); //向下调整 void _AdjustUp(size_t index); //向上调整 bool _Push(T1& data) { _array.push_back(data); _AdjustUp(); } bool _Pop() //头删法 { if (!_array.empty()) { size_t size = _array.size(); swap(_array[0], _array[size - 1]); _array.pop_back(); _AdjustDown(0); } else { return false; } } T1 _Top() { return _array[0]; } size_t _Size() { return _array.size(); } protected: vector<T1> _array; };
template<class T1,template<class>class T2> void Heap<T1, T2>::_AdjustDown(size_t index) //向下调整 { T2<T1> compare; size_t child = index * 2 + 1; while (child < _array.size()) { if (child + 1<_array.size() && compare(_array[child + 1], _array[child])) { ++child; } if (compare(_array[child], _array[index])) { swap(_array[child], _array[index]); index = child; child = child * 2 + 1; } else { break; } } }
template<class T1, template<class>class T2> void Heap<T1, T2>::_AdjustUp(size_t index) //向上调整 { T2<T1> compare; size_t parent = (index-1)/2; while (index) { if (compare(_array[index], _array[parent])) { swap(_array[index], _array[parent]); index = parent; parent = (parent - 1) / 2; } else { break; } } }
堆的应用之优先级队列:
template<class T,template<class> class T2> class PriorityQueue { public: void Push(const T& data) { _heap.Push(data); } void Pop() { _heap.Pop(); } T& Top() { return _heap._vector[0]; } int Size() { return _heap._vector.size(); } bool Empty() { return _heap._vector.empty() ? 1 : 0; } protected: Heap<T, T2> _heap; };
测试:
void Test() { PriorityQueue<int, Max_Heap> _PriorityQueue; vector<int> Vector = { 4, 6, 8, 7, 8}; for (int i = 0; i < 5; ++i) _PriorityQueue.Push(Vector[i]); for (int i = 0; i < 5; ++i) { cout << "Top: " << _PriorityQueue.Top() << endl; _PriorityQueue.Pop(); cout << "当前优先级队列的大小为:" << _PriorityQueue.Size() << endl; cout << "当前优先级队列是否为空:" << _PriorityQueue.Empty() << endl << endl; } }
堆的应用之二,堆排序