标签:
本节研究堆heap的相关操作实现;
说明几点
(1)堆分为大根堆和小根堆;大根堆的根为最大值,每一个节点的值都不小于其孩子的值;
(2)可以利用大根堆实现升序排序;主要是利用大根堆的头和需要排序的最后一个数字交换的思想;
(3)使用大根堆实现最大优先级队列,类似stl中queue的操作,只是对于元素在队列中的元素优先级是不一样的,在最大优先级中,队列头为值最大元素;可利用大根堆来维护一个最大优先级队列;向优先级队列中push元素,类似像堆的末尾添加一个元素,然后使用_makeHeapUp寻找该元素的存放位置,进而维护大根堆;当向优先级队列中pop元素,将首元素和最后一个元素对换,然后使用_makeHeapDown来从首元素向下维护大根堆,类似堆排序,最后再将尾部元素pop_back;
(4)stl中使用sort_heap对容器进行堆排序,注意该容器需保证已经符合堆的特性;
(5)stl中使用make_heap对对一个容器中的值进行建堆;pop_heap,push_heap分别对队进行出堆(出堆之后,出堆值保存在容器的尾部)和入堆(入堆之前,入堆值已经保存在容器的尾部);
inline int left(int parent) { return parent*2 + 1; } inline int right(int parent) { return parent*2 + 2; } inline int parent(int child) { return (child-1) / 2; } void _makeHeapDown(vector<int>& array, int top, int end) { while (left(top) < end) { int leftChild = left(top); int rightChild = right(top); int min = top; if (array[top] < array[leftChild]) min = leftChild; if (rightChild < end && array[min] < array[rightChild]) min = rightChild; if (top == min) break; swap(array[min], array[top]); top = min; } } void heapSort(vector<int>& array) { for (int i = array.size() / 2; i >= 0; --i) _makeHeapDown(array, i, array.size()); for (int i = array.size()-1; i >= 1; --i) { swap(array[i], array[0]); _makeHeapDown(array, 0, i); } }
说明几点:
(1)在堆排序中,仅仅使用了向下维护堆特性,但是优先级队列中使用了向上和向下维护堆特性;
inline int left(int parent) { return parent*2 + 1; } inline int right(int parent) { return parent*2 + 2; } inline int parent(int child) { return (child-1) / 2; } void _makeHeapDown(vector<int>& array, int top, int end) { while (left(top) < end) { int leftChild = left(top); int rightChild = right(top); int min = top; if (array[top] < array[leftChild]) min = leftChild; if (rightChild < end && array[min] < array[rightChild]) min = rightChild; if (top == min) break; swap(array[min], array[top]); top = min; } } void _makeHeapUp(vector<int>& array, int last) { if (last < 0) return; int value = array[last]; while (last > 0) { int parentIndex = parent(last); if (array[parentIndex] < value) { array[last] = array[parentIndex]; last = parentIndex; } else { break; } } array[last] = value; } class PriorityQueue { public: int size() const { return _seq.size(); } bool empty() const { return _seq.empty(); } void push(int x) { _seq.push_back(x); _makeHeapUp(_seq, _seq.size()-1); } int top() { if (_seq.empty()) return -1; return _seq[0]; } void pop() { if (_seq.empty()) return; swap(_seq[0], _seq[_seq.size()-1]); _makeHeapDown(_seq, 0, _seq.size()-1); _seq.pop_back(); } private: vector<int> _seq; };
标签:
原文地址:http://blog.csdn.net/skyuppour/article/details/45647983