c語言實現赫夫曼樹的構建以及生成赫夫曼編碼(《資料結構》演算法6.12)
阿新 • • 發佈:2018-12-22
這個程式是根據《資料結構》演算法6.12用c語言實現的程式,赫夫曼樹就不多說了,直接看程式碼,程式碼上都有註釋。
下面程式碼:
#include<stdio.h> #include<iostream> #include<stdlib.h> #include<string.h> #include<algorithm> #define MAX_NUM 100 #define inf 2000000000 using namespace std; typedef struct { unsigned int weight;//權值 unsigned int parent,lchild,rchild;//父節點,孩子結點的權值 }HTNode,*HuffmanTree; typedef char * * HuffmanCode;//二維字元陣列 int s1,s2;//最小的兩個結點 void Select(HuffmanTree &HT,int x){//選出無父結點,並且權值最小的兩個結點,賦值給s1,s2 int i,min1=inf,min2=inf; for(i=1;i<=x;i++){//找最小 if(HT[i].weight<min1&&HT[i].parent==0){min1=HT[i].weight;s1=i;} } for(i=1;i<=x;i++){//找次小 if(HT[i].weight<min2&&i!=s1&&HT[i].parent==0){ min2=HT[i].weight;s2=i; } } } void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){//根據輸入的結點的權值和個數來構建赫夫曼樹 if(n<=1)return; int m=2*n-1;//n個葉子,有2*n-1個結點 int i; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0號單元未用 HuffmanTree p; for(p=HT+1,i=1;i<=n;i++,p++,w++) {//葉子結點賦值 p->weight=*w;p->parent=0;p->lchild=0;p->rchild=0; } for(;i<=m;i++,p++) {//非葉子結點初始化 p->weight=0;p->parent=0;p->lchild=0;p->rchild=0; } for(i=n+1;i<=m;i++){ Select(HT,i-1);//選出最小的兩個無父節點的結點 HT[s1].parent=i;HT[s2].parent=i; HT[i].lchild=s1;HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } //----------下面是將每個結點的赫夫曼編碼存入二維字元陣列 HC=(HuffmanCode)malloc((n+1)*sizeof(char *));//申請一段以HC為首地址的記憶體,可以看成二維字元陣列 ,這裡先申請了第一維 char *cd=(char *)malloc(n*sizeof(char));//申請一段臨時工作空間 cd[n-1]='\0';//編碼結束符 for(i=1;i<=n;i++){ int start=n-1,c,f; for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent){//從葉子到根逆向求編碼 if(HT[f].lchild==c)cd[--start]='0';//如果當前結點是父節點的左孩子,則存一個1 else cd[--start]='1';//反之 } HC[i]=(char *)malloc((n-start)*sizeof(char));//申請第二維 strcpy(HC[i],&cd[start]);//將編碼從工作空間存入赫夫曼編碼表中 } free(cd); //釋放臨時空間 } int main(){ HuffmanTree HT; HuffmanCode HC; int w[MAX_NUM],n; printf("輸入結點的個數:\n"); scanf("%d",&n); printf("輸入每個結點的權值:\n"); for(int i=0;i<n;i++) scanf("%d",&w[i]); HuffmanCoding(HT,HC,w,n); for(int i=1;i<=n;i++) printf("%d的赫夫曼編碼為:%s\n",HT[i].weight,HC[i]); return 0; }