最小堆的概念:所有父节点的值小于或等于两子节点的值,并且它所有元素按完全二叉树的顺序存储方式存放在一个一维数组中。
如图:
关于堆的操作:
1.建立最小堆:将普通数组转换成堆,转换完成后,数组就满足最小堆的特性,即所有父节点的值小于或等于两个子节点.
具体实现:
template<class Type>
class MinHeap
{
public:
MinHeap(size_t sz = DefaultSize)//构造函数:建立空堆
{
capacity = sz>DefaultSize?sz:DefaultSize;
heap = new Type[capacity];
size = 0;
}
MinHeap(Type ar[], int n)//构造函数:通过一个数组建堆
{
capacity = n>DefaultSize?n:DefaultSize;
heap = new Type[capacity];
for(int i=0; i<n; ++i)
{
heap[i] = ar[i];
}
size = n;
int pos = n/2-1;//找到堆的最后一个分支
while(pos >= 0)
{
SiftDown_Min(pos,n);
pos--;
}
}
~MinHeap()
{
delete []heap;
heap = NULL;
}
private:
enum{DefaultSize=10};
Type *heap;
size_t capacity;
size_t size;
};
2.通过下滑调整算法,将堆调整为最小堆。
具体实现:
void SiftDown_Min(int start, int end)
{
int i = start;//i从堆的最后一个分支开始,即i=pos=3;
int j = 2*i+1;//左子树
Type tmp = heap[i];
while(j < end)
{
if(j<end-1 && (heap[j] > heap[j+1]))//让j指向两子女中的小者
j = j+1;
if(tmp < heap[j])
break;
else
{
heap[i] = heap[j];
i = j;
j = 2*i+1;
}
}
heap[i] = tmp;
}
总结:只要熟练掌握了最小堆的概念,则问题便会迎刃而解。