資料結構——哈夫曼樹的實現以及編碼(C語言實現)
阿新 • • 發佈:2018-12-20
1、問題描述
利用哈夫曼編碼進行通訊可以大大提高通道利用率,縮簡訊息傳輸時間,降低傳輸成本。構造哈夫曼樹時,首先將由n個字
符形成的n個葉子結點存放到陣列HuffNode的前n個分量中,然後根據哈夫曼方法的基本思想,不斷將兩個較小的子樹合併為一個
較大的子樹,每次構成的新子樹的根結點順序放到HuffNode陣列中的前n個分量的後面。
通俗的來講,哈弗曼樹就是一種廣泛應用的二叉樹,哈弗曼樹可以用來構造最優編碼,用於資訊的傳輸,壓縮等方面
哈弗曼樹也可以理解為,最小二叉樹,最優二叉樹
2、資料結構設計
#define MAXVALUE 32767 typedef struct{ //哈夫曼樹結構體 int weight; //輸入權值 int parent,lchild,rchild; //雙親節點,左孩子,右孩子 }HNodeType; typedef struct{ //哈夫曼編碼結構體 int bit[8]; //存放當前結點的哈夫曼編碼 int start; //bit[start]-bit[8[存放哈夫曼編碼 }HCodeType; HNodeType HuffNode[8]; //定義全域性變數陣列HuffNode存放哈夫曼樹 HCodeType HuffCode[8]; //定義全域性變數陣列HuffCode存放哈夫曼編碼 int n; //定義全域性變數n表示葉子結點個數
3、函式說明
void CreateHuffTree(void); //構造哈夫曼樹
void PrintHuffTree(void); //輸出哈夫曼樹
void CreateHuffCode(void); //構造哈夫曼編碼
void PrintHuffcode(void); //輸出每個葉子結點的哈夫曼編碼
4、函式功能實現
<1>構造哈弗曼樹
void CreateHuffTree(void){ //構造哈夫曼樹 int i,j,a,b,x1,x2; scanf("%d",&n); //輸入葉子節點個數 for(i=1;i<2*n;i++) //HuffNode 初始化 { HuffNode[i].weight=0; HuffNode[i].parent=-1; HuffNode[i].lchild=-1; HuffNode[i].rchild=-1; } printf("輸入%d個節點的權值\n",n); for(i=1;i<=n;i++) scanf("%d",& HuffNode[i].weight);//輸入N個葉子節點的權值 for(i=1;i<n;i++){ //構造哈夫曼樹 a=MAXVALUE; b=MAXVALUE; x1=0; x2=0; for(j=1;j<n+i;j++){ //選取最小和次小兩個權值 if(HuffNode[j].parent==-1&&HuffNode[j].weight<a){ b=a; x2=x1; a=HuffNode[j].weight; x1=j; } else if(HuffNode[j].parent==-1&&HuffNode[j].weight<b){ b=HuffNode[j].weight; x2=j; } } HuffNode[x1].parent=n+i; HuffNode[x2].parent=n+i; HuffNode[n+i].weight=HuffNode[x1].weight+HuffNode[x2].weight; HuffNode[n+i].lchild=x1; HuffNode[n+i].rchild=x2; } }
<2>輸出哈弗曼樹
void PrintHuffTree() { //輸出哈夫曼樹
int i;
printf("\n哈夫曼樹各項資料如下表所示:\n");
printf(" 結點i weight parent lchid rchild\n");
for(i=1;i<2*n;i++)
printf("\t%d\t%d\t%d\t%d\t%d\n",i,HuffNode[i].weight,HuffNode[i].parent,
HuffNode[i].lchild,HuffNode[i].rchild);
printf("\n");
}
<3>構造哈夫曼編碼
void CreateHuffCode(void){ //構造哈夫曼編碼
HCodeType cd;
int i,j,c,p;
for(i=1;i<=n;i++){
cd.start=n;
c=i;
p=HuffNode[c].parent;
while(p!=-1){
if(HuffNode[p].lchild==c)
cd.bit[cd.start]=0;
else
cd.bit[cd.start]=1;
cd.start--;
c=p;
p=HuffNode[c].parent;
}
for(j=cd.start+1;j<=n;j++)
HuffCode[i].bit[j]=cd.bit[j];
HuffCode[i].start=cd.start;
}
}
<4>輸出哈夫曼編碼
void PrintHuffcode(void){ //輸出每個葉子結點的哈夫曼編碼
int i,j;
printf("每個葉子結點的哈夫曼編碼為:\n");
for(i=1;i<=n;i++)
{ for(j=HuffCode[i].start+1;j<=n;j++)
printf("%d",HuffCode[i].bit[j]);
printf("\n");
}
}
<5>主函式
int main(void){
printf("輸入葉子節點個數\n");
CreateHuffTree(); //構造哈夫曼樹
PrintHuffTree(); //輸出哈夫曼樹
CreateHuffCode(); //構造哈夫曼編碼
PrintHuffcode(); //輸出每個葉子結點的哈夫曼編碼
return 0;
}
程式執行結果如下