标签:
本节研究堆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