一、堆
最大堆的定義與創建
/* 創建容量爲MaxSize的空的最大堆 */
#define MAXDATA 1000 /* 該值應根據具體情況定義爲大於堆中所有可能元素的值 */
struct MaxHeap {
ElementType *Data; /* 存儲元素的數組 */
int Size; /* 堆中當前元素個數 */
int Capacity; /* 堆的最大容量 */
MaxHeap(int Maxsize){
Size = 0;
Capacity = MaxSize;
Data = new int[MaxSize];
Data[0] = MAXDATA; /* 定義"哨兵"爲大於堆中所有可能元素的值*/
}
};
最大堆的插入和刪除
bool IsFull( MaxHeap* H )
{
return (H->Size == H->Capacity);
}
bool Insert( MaxHeap* H, ElementType X )
{ /* 將元素X插入最大堆H,其中H->Data[0]已經定義爲哨兵 */
int i;
if ( IsFull(H) ) {
printf("最大堆已滿");
return false;
}
i = ++H->Size; /* i指向插入後堆中的最後一個元素的位置 */
for ( ; H->Data[i/2] < X; i/=2 )
H->Data[i] = H->Data[i/2]; /* 上濾X */
H->Data[i] = X; /* 將X插入 */
return true;
}
#define ERROR -1 /* 錯誤標識應根據具體情況定義爲堆中不可能出現的元素值 */
bool IsEmpty( MaxHeap* H )
{
return (H->Size == 0);
}
ElementType DeleteMax( MaxHeap* H )
{ /* 從最大堆H中取出鍵值爲最大的元素,並刪除一個結點 */
int Parent, Child;
ElementType MaxItem, X;
if ( IsEmpty(H) ) {
printf("最大堆已爲空");
return ERROR;
}
MaxItem = H->Data[1]; /* 取出根結點存放的最大值 */
/* 用最大堆中最後一個元素從根結點開始向上過濾下層結點 */
X = H->Data[H->Size--]; /* 注意當前堆的規模要減小 */
for( Parent=1; Parent*2<=H->Size; Parent=Child ) {
Child = Parent * 2;
if( (Child!=H->Size) && (H->Data[Child]<H->Data[Child+1]) )
Child++; /* Child指向左右子結點的較大者 */
if( X >= H->Data[Child] ) break; /* 找到了合適位置 */
else /* 下濾X */
H->Data[Parent] = H->Data[Child];
}
H->Data[Parent] = X;
return MaxItem;
}
二、哈弗曼樹和哈夫曼編碼
哈夫曼樹又稱最優二叉樹,是一種帶權路徑長度最短的二叉樹。所謂樹的帶權路徑長度,就是樹中所有的葉結點的權值乘上其到根結點的路徑長度(若根結點爲0層,葉結點到根結點的路徑長度爲葉結點的層數)。樹的路徑長度是從樹根到每一結點的路徑長度之和,記爲WPL=(W1* L1+W2* L2+W3* L3+…+Wn* Ln),N個權值Wi(i=1,2,…n)構成一棵有N個葉結點的二叉樹,相應的葉結點的路徑長度爲Li(i=1,2,…n)。可以證明霍夫曼樹的WPL是最小的。
在計算機數據處理中,霍夫曼編碼使用變長編碼表對源符號(如文件中的一個字母)進行編碼,其中變長編碼表是通過一種評估來源符號出現機率的方法得到的,出現機率高的字母使用較短的編碼,反之出現機率低的則使用較長的編碼,這便使編碼之後的字符串的平均長度、期望值降低,從而達到無損壓縮數據的目的。
哈弗曼樹構造
給出5個葉子結點,他們權值分別爲{1,2,3,4,5}
哈夫曼樹沒有度爲1的結點!!!
哈弗曼編碼
三、集合