1.主要的儲存結構
struct HeapStruct
{
int Capacity;//最大容量
int Size;//當前容量
ElementType *Elements;//數組入口地址
};
typedef struct HeapStruct *PriorityQueue;
結構體HeapStruct實際上是一個數組,二元堆積的底層實現是一個完全二叉樹,因此可以很方便的使用數組實現。
完全二叉樹的一個重要性質是可以明確給出父子之間的位置關係:
設節點v的秩為i(設根節點秩為0),則
若v有左子,左子的秩=2 * i + 1;
若v有右子,右子的秩=2 * i + 2;
若v有父親,父親的秩=(i - 1) / 2;
2.主要堆操作
為了維持堆序性,主要涉及的堆操作有兩個,即插入與刪除節點。
2.1插入節點-O(logN)
插入節點的演算法為,
1.新節點插入堆尾。
2.迴圈比較該節點與它的父節點;
2.1若該節點<父節點,則交換之;
2.2否則,停止與當前位置,即為插入位置。
這個迴圈過程即為上濾過程。
這裡設定一個啞元節點Element[0],其中放入一個極小值,以便迴圈過程終止,這樣做可以避免在迴圈體內多加一條判斷語句。則現在堆頂為Element[1],父子之間的位置關係:
設節點v的秩為i(設根節點秩為1),則
若v有左子,左子的秩=2 * i;
若v有右子,右子的秩=2 * i + 1;
若v有父親,父親的秩=i / 2;
/* H->Element[ 0 ] is a sentinel */
void Insert( ElementType X, PriorityQueue H )
{
int i;
if( IsFull( H ) )
{
Error( "Priority queue is full" );
return;
}
for( i = ++H->Size; H->Elements[ i / 2 ] > X; i /= 2 )
H->Elements[ i ] = H->Elements[ i / 2 ];
H->Elements[ i ] = X;
}