哈夫曼编码译码 C语言,【求助】严蔚敏版数据结构 哈夫曼编码译码
該樓層疑似違規已被系統折疊?隱藏此樓查看此樓
#include
#include
#include
typedef char* HuffmanCode;/*動態分配數組,存儲哈夫曼編碼*/
typedef struct
{
unsigned int weight ; /* 用來存放各個結點的權值*/
unsigned int parent, LChild,RChild ; /*指向雙親、孩子結點的指針*/
}HTNode, * HuffmanTree; /*動態分配數組,存儲哈夫曼樹*/
void select(HuffmanTree *ht,int n, int *s1, int *s2) /*選擇霍夫曼樹中權值最小的兩個結點
并返回他們的序號*/
{
int i;
int min;
for(i=1; i<=n; i++)
{
if((*ht)[i].parent == 0) //雙親結點為0
{
min = i; // 將第一個雙親結點為0的葉結點序號給min
i = n+1; //將i改為非葉結點
}
}
for(i=1; i<=n; i++)
{
if((*ht)[i].parent == 0)
{ //比較各葉節點權值與剛才min號結點比較
if((*ht)[i].weight < (*ht)[min].weight)
min = i; //MIN放權值最小的兩個結點序號小的那個
}
}
*s1 = min; //s1存放這個小的序號
for(i=1; i<=n; i++)
{
if((*ht)[i].parent == 0 && i!=(*s1)) //再搜索除s1以外的葉結點
{
min = i; //重復上面取最小葉結點的過程
i = n+1;
}
}
for(i=1; i<=n; i++)
{
if((*ht)[i].parent == 0 && i!=(*s1))
{
if((*ht)[i].weight < (*ht)[min].weight)
min = i; //這個min存放權值第二小的結點序號再給s2
}
}
*s2 = min;
} //最后將最小的兩個結點的序號返回
void CrtHuffmanTree(HuffmanTree *ht , int *w, int n)
{ /* w存放已知的n個權值,構造哈夫曼樹ht */
int m,i; //m是結點總數
int s1,s2;
m=2*n-1;
*ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); /*0號單元未使用*/
for(i=1;i<=n;i++)
{/*1-n號放葉子結點,初始化*/
(*ht)[i].weight = w[i];
(*ht)[i].LChild = 0;
(*ht)[i].parent = 0;
(*ht)[i].RChild = 0;
}
for(i=n+1;i<=m;i++)
{
(*ht)[i].weight = 0;
(*ht)[i].LChild = 0;
(*ht)[i].parent = 0;
(*ht)[i].RChild = 0;
} /*非葉子結點初始化*/
/* ------------初始化完畢!對應算法步驟1---------*/
for(i=n+1;i<=m;i++) /*創建非葉子結點,建哈夫曼樹*/
{ /*在(*ht)[1]~(*ht)[i-1]的范圍內就是選擇葉子結點
建成一步后,增加了一個雙親節點,則此時需要增加一個結點搜索最小值
由于先前的葉子結點的雙親結點不是0,則不影響搜索
選擇兩個parent為0且weight最小的結點,其序號分別賦值給s1、s2返回*/
select(ht,i-1,&s1,&s2);
(*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;
}
}/*哈夫曼樹建立完畢*/
void outputHuffman(HuffmanTree HT, int m) //遞歸輸出霍夫曼樹
{
if(m!=0)
{
printf("%d ", HT[m].weight);
outputHuffman(HT,HT[m].LChild);
outputHuffman(HT,HT[m].RChild);
}
}
void CrtHuffmanCode(HuffmanTree *ht, HuffmanCode *hc, int n)
/*從葉子結點到根,逆向求每個葉子結點對應的哈夫曼編碼*/
{
char *cd; //cd是用來存放需要編碼的0,1.
int i;
unsigned int c;
int start;
int p; //指向第i個葉子結點的雙親結點
hc=(HuffmanCode *)malloc((n+1)*sizeof(char *)); /*分配n個編碼的頭指針*hc即使hc[n]
n個編碼的頭指針0號未使用*/
cd=(char * )malloc(n * sizeof(char )); /*分配求當前編碼的工作空間即是
將那些個0,1存到數組中 0,1以字符形式輸出*/
cd[n-1]='\0'; /*從右向左逐位存放編碼,首先存放編碼結束符*/
for(i=1;i<=n;i++) /*求n個葉子結點對應的哈夫曼編碼*/
{
start=n-1; /*初始化編碼起始指針*/
for(c=i,p=(*ht)[i].parent; p!=0; c=p,p=(*ht)[p].parent) /*從葉子到根結點求編碼*/
if( (*ht)[p].LChild == c)
cd[--start]='0'; /*左分支標0*/
else
cd[--start]='1'; /*右分支標1*/
hc[i]=(char *)malloc((n-start)*sizeof(char)); /*為第i個編碼分配空間*/
strcpy(hc[i],&cd[start]); /*將當前到末尾的霍夫曼編碼賦給hc數組*/
}
free(cd);
for(i=1;i<=n;i++)
printf("%d編碼為%s\n",(*ht)[i].weight,hc[i]);
}
void main()
{
HuffmanTree HT;
HuffmanCode HC; //定義編碼指針 即編碼數組,存放所有葉子結點的0,1編碼
int *p;
int i,n; // the number of elements;
int val; // the weight of a element;
int m;
printf("input the total number of the Huffman Tree:" );
scanf("%d",&n); //有n個已知權值的結點
p=(int *)malloc((n+1)*sizeof(int)); //分配給權值空間
for(i=1;i<=n;i++)
{
printf("input the %d element's weight:",i);
scanf("%d",&val);
p[i]=val;
}
CrtHuffmanTree(&HT,p,n);
m = 2*n-1;
outputHuffman(HT,m); //輸出所有的霍夫曼結點的權值
printf("\n");
CrtHuffmanCode(&HT,&HC,n); //創建霍夫曼編碼,hc是編碼數組
}
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的哈夫曼编码译码 C语言,【求助】严蔚敏版数据结构 哈夫曼编码译码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 以太网转wifi,LINUX
- 下一篇: c语言程序设计第二章的答案,C语言程序设