1. 程式人生 > >樹-哈夫曼編碼

樹-哈夫曼編碼

creat ++ .com truct col sca 哈夫曼編碼 最優 序號

哈夫曼樹(最優二叉樹)

每個葉子節點都有權值,權值越大的葉節點越靠近根節點,而權值越小的葉節點越遠離根節點

建立規則:

依據給出的n個權值,選擇最小的兩個權值作為一棵新的二叉樹的左右子樹,並且新的根節點的權值為左右子樹權值之和

將新根節點與剩下的有權值的節點重復此操作直至只剩一個根節點

技術分享圖片

哈夫曼編碼:

在哈夫曼樹的基礎上,規定哈夫曼樹中的左分支代表0,右分支代表1,從根節點到每個葉節點所經過的路徑分支組成的0和1的序列便是該節點對應字符的編碼

技術分享圖片

源碼:

親測有效

//哈夫曼樹及哈夫曼編碼 

#include<stdio.h>
#include<malloc.h>
#define
MAXLEN 100 typedef struct node{ int weight; //整型權值變量 int lchild,rchild,parent; //左孩子,右孩子,雙親 }HFNode; typedef HFNode HFMT[MAXLEN]; int n; int InitHFMT(HFMT T) //初始化 { int i; printf("\n\t\t請輸入共有多少個權值(小於100):
"); //葉子節點數 scanf("%d",&n); for(i = 0;i < 2*n-1;i++) { T[i].weight = 0; T[i].lchild = -1; T[i].rchild = -1; T[i].parent = -1; } return 0; } int InputWeight(HFMT T) //輸入權值 { int w,i; for(i = 0;i < n;i++) { printf(
"\n\t\t請輸入第%d個葉子節點的權值:",i+1); scanf("%d",&w); T[i].weight = w; } return 0; } int SelectMin(HFMT T,int i,int *p1,int *p2) //選擇兩個節點中小的節點 { long min1 = 999999; //預設兩個值,使它大於可能出現的最大權值 long min2 = 999999; int j; for(j = 0;j <= i;j++) { if(T[j].parent == -1) { if(T[j].weight < min1) { min1 = T[j].weight; //找出最小的權值,通過*p1帶回權值 *p1 = j; } } } for(j = 0;j <=i;j++) { if(T[j].parent == -1) { if(T[j].weight < min2 && j != (*p1)) { min2 = T[j].weight; //找出次最小的權值,通過*p2帶回序號 *p2 = j; } } } return 0; } int CreatHFMT(HFMT T) //構建哈夫曼樹,T(2*n-1)為根節點 { int i,p1,p2; InitHFMT(T); InputWeight(T); for(i = n;i < 2*n-1;i++) { SelectMin(T,i-1,&p1,&p2); T[p1].parent = T[p2].parent = i; T[i].lchild = p1; T[i].rchild = p2; T[i].weight = T[p1].weight + T[p2].weight; } return 0; } int PrintHFMT(HFMT T) //輸出向量狀態表 ,打印哈夫曼樹 { printf("\n\t\t哈夫曼樹的各邊顯示:"); int i=0,k=0; for(i = 0;i < 2*n-1;i++) { if(T[i].lchild != -1) { if( !(k%2) ) printf("\n"); printf("\t\t(%d,%d),(%d,%d)",T[i].weight,T[ T[i].lchild ].weight,T[i].weight,T[ T[i].rchild ].weight); k++; } printf("\n\n"); } return 0; } int hfnode(HFMT T,int i) { int j; j = T[i].parent; if(j != -1) { if(T[j].lchild == i) printf("0"); else printf("1"); i = j; hfnode(T,i); } return 0; } int huffmannode(HFMT T) //求哈夫曼編碼 { printf("\t\t輸入的權值對應的逆置的哈夫曼編碼(從葉節點到根節點):"); int i,a,k = 0; for(i = 0;i < n;i++) { a = i; if(!(k%2)) printf("\n"); printf("\t\t%d:",T[i].weight); k++; hfnode(T,i); i = a; } return 0; } int main() { HFMT HT; CreatHFMT(HT); PrintHFMT(HT); huffmannode(HT); printf("\n"); return 0; }

樹-哈夫曼編碼