C語言哈夫曼樹和哈夫曼編碼的實現

2021-07-26 06:58:15 字數 1826 閱讀 2692

哈夫曼樹是一類帶權路徑(wpl)最短的的樹。下面說一下實現**:

首先仍然是型別定義:

typedef char **huffmancode;

typedef structhtnode,*huffmantree;

選擇函式:

void select(huffmantree ht, int i,int *s1,int *s2)

else

if (ht[j].parent == 0 && ht[*s2].weight > ht[j].weight)

*s2 = j;

}}

先讓s1和s2指向0號位置(在下面建立函式中會把s1和s2號位置的權值設定為最大值),在已經儲存權值的位置檢查是否存在雙親為0並且權值比s1小的節點,如果有,則將s1的儲存的位置賦值給s2(由於s1必然小於或等於s2,所以當發現有權值比s1小的節點時,s1中儲存的節點變為權值第二小的節點,而s2正好用來儲存第二小節點的位址),之後讓j的值賦值給*s1。如果不存在權值比s1小的節點,則判斷它的權值是否比s2的小(其權值有可能介於s1指向節點的權值和s2指向節點權值之間)。如果小於s2指向的權值,則將j賦值給*s2。

建立哈夫曼樹:

htnode *createhuffmantree(huffmantree ht, int n)

ht[0].weight = 9999;

for (i = 1; i <= n; i++)

scanf("%d", ht[i].weight);

for (i = n + 1; i <= m; i++)

return ht;

}

先判斷這棵樹是否只有乙個節點,如果僅僅只有乙個,則不需要建立哈夫曼樹,返回。確定m的值,哈夫曼數所有節點的數目。為哈夫曼樹分配(m+1)個節點空間,並將所有節點的雙親、左右孩子均賦值為0,表示沒有雙親、左右孩子。將0號節點的權值賦值為乙個很大的值,並輸入n個節點的權值。最後,從n+1號結點開始作為雙親結點,依次找到最小兩個節點的位置,並將其雙親設定為i,將i號節點的左右子樹分別設定為s1、s2,權值為左右子樹權值之和。直到i<=m為止。

構造哈夫曼編碼:

huffmancode createhuffmancode(huffmantree ht, huffmancode hc, int n)

hc[i] = (char *)malloc(sizeof(char)*(n - start));

strcpy(hc[i], &cd[start]);

} delete cd;

return hc;

}

為hc分配n+1個char *空間,為cd分配n個空間,並將』\0』賦值給cd最後一位。依次獲得哈夫曼編碼:每一次都將start定位到n-1處,即cd的最後一位,然後讓c等於要獲得編碼的位置(即i),f等於c的雙親,當c的雙親不為0的時候重複執行將start向前移動一位,判斷c是不是f號節點的左子樹,如果是,則cd[start]則為』0『(char型別),否則為』1』,c移動到原來c的雙親上,f移動到原來f的雙親上。為hc[i]分配適當空間(n-start個),將cd的內容複製到hc[i]中。獲得所有哈夫曼編碼後,釋放cd分配的空間。

加入main():

哈夫曼編碼 哈夫曼樹

1.定義 哈夫曼編碼主要用於資料壓縮。哈夫曼編碼是一種可變長編碼。該編碼將出現頻率高的字元,使用短編碼 將出現頻率低的字元,使用長編碼。變長編碼的主要問題是,必須實現非字首編碼,即在乙個字符集中,任何乙個字元的編碼都不是另乙個字元編碼的字首。如 0 10就是非字首編碼,而0 01不是非字首編碼。2....

哈夫曼樹 哈夫曼編碼

定義從a結點到b結點所經過的分支序列為從a結點到b結點的路徑 定義從a結點到b結點所進過的分支個數為從a結點到b結點的路徑長度 從二叉樹的根結點到二叉樹中所有結點的路徑長度紙盒為該二叉樹的路徑長度 huffman樹 帶權值路徑長度最小的擴充二叉樹應是權值大的外界點舉例根結點最近的擴充二叉樹,該樹即為...

哈夫曼編碼 哈夫曼樹

哈夫曼樹是乙個利用權值進行優化編碼的乙個比較奇怪的樹,他的實現比較簡單,用途也比較單一。哈夫曼樹的實現,實現要求 通過哈夫曼樹可以保證在編碼過程中不會出現例如 1000和100這樣的編碼規則,否則就會編碼失敗,因為1000和100在某些情況下的編碼會一模一樣。通過哈夫曼樹可以保證權值大的值進行編碼時...