浙大数据结构
堆用完全二叉树的结构形式组织存储,表现为结构性,任一结点的关键字是其所有子树结点的最大值(称这样的堆为最大堆)或者最小值(称这样的堆为最小堆),表现为有序性。
可以按从上往下,从左到右的顺序排序,把二维结构的完全二叉树转换成一维结构的数组进行存储。通过下标进行访问时,任意父结点的下标正好是其左右儿子结点的二分之一倍。
最小堆的建立
以数组的形式存储了一组数据来表示完全二叉树后,先满足了最小堆的结构性,然后通过调整结点数据才满足最小堆的有序性。
通过已使用的最后一个数组单元下标访问其父结点,该父结点就是最后一个有儿子的结点,往后都是叶子结点。从最后一个父结点开始往前调整使每一棵子树都满足有序性。
/* 最小堆的建立 */
void BuilMinHeap(MinHeap *H){
/* BuilMinHeap()使用DeleteMin()相似原理 */
/* 调整元素使其满足有序性 */
int i;
i = H->Size/2;
for(i; i>=1; i--){
DHeap(H, i);
}
}
void DHeap(MinHeap *H, int p){
int Parent, Child;
ElementType temp;
temp = H->Elements[p]; //取出根结点
for( Parent=p; Parent*2<=H->Size; Parent=Child ) {
Child = Parent * 2;
if(Child != H->Size &&
H->Elements[Child]->Weight > H->Elements[Child+1]->Weight)
Child++; //Child指向左右子结点的权值较小者
if( temp->Weight <= H->Elements[Child]->Weight ) break; //找到了合适位置
else H->Elements[Parent] = H->Elements[Child];
}
H->Elements[Parent] = temp;
}
弹出(删除)结点
建成最小堆后弹出权值最小结点(根结点)与最小堆的建立使用的方案非常相似。每次弹出根节点后使用最后一个叶子结点填充根节点,再向下过滤寻找适合的位置进行存储。
/* 弹出(删除)结点 */
ElementType DeleteMin(MinHeap *H){
ElementType MinItem, temp;
int Parent, Child;
if(H->Size == 0){
cout << "堆空!" << endl;
return NULL;
}
MinItem = H->Elements[1];
temp = H->Elements[H->Size--];
for(Parent=1; Parent*2<=H->Size; Parent=Child){
Child = Parent * 2;
if(H->Size !=