日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

huffman(赫夫曼编码)之C/C++实现

發(fā)布時間:2024/5/8 c/c++ 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 huffman(赫夫曼编码)之C/C++实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

有點(diǎn)兒興奮,有點(diǎn)兒緊張,這是我人生發(fā)的第一篇正式的blog,在進(jìn)入正文之前,請容許我說一點(diǎn)兒序言,之所以發(fā)這一blog文章,一來是想記錄下自己一天做了些什么,學(xué)了些什么,所謂:好記性不如爛筆頭,以前沒有體會到這一點(diǎn)兒的好,在經(jīng)過一個項(xiàng)目的總結(jié)之后,看到同事在做一個項(xiàng)目的總結(jié)文檔和自己的一比,才知道,原來實(shí)時記錄自己所學(xué),所想的重要性,成功是一點(diǎn)兒一點(diǎn)兒積累起來的;二來,也是便于自己經(jīng)常的復(fù)習(xí)所學(xué)的東西,不致于要用的時候,到處找,像無頭蒼蠅一般;

好了,讓我們進(jìn)入正題吧,今天所學(xué)的是用代碼實(shí)現(xiàn)“赫夫曼編碼”。當(dāng)然,什么是赫夫曼編碼呢?在此,我就不多說了,因?yàn)楸救艘膊皇呛芰私?#xff0c;只知道“赫夫曼編碼”又稱“前綴編碼”,在《數(shù)據(jù)結(jié)構(gòu)(C語言)版——嚴(yán)蔚敏感編著》中第146頁有些許的介紹。有興趣的朋友可以下去多了解學(xué)習(xí)一下,本人只注重代碼的實(shí)現(xiàn)。謝謝!

讓我先來看看生成“赫夫曼編碼”所需的數(shù)據(jù)結(jié)構(gòu):

typedef struct_huffman_node

{

unsigned int weight;

unsigned int parent,lchild,rchild;

_huffman_node(const int w,const int p,const int l ,const int r)

{

weight=w;parent=p;lchild=l;rchild=r;

}

bool operator<(const _huffman_node t)

{

return weight<t.weight;

}

}HTNode,*HuffmanTree;

typedef char ** HuffmanCode;//動態(tài)分配數(shù)組存儲赫夫曼編碼表

注:之所以把父指針、左子樹、右子樹定義為unsigned int是因?yàn)槲也捎玫氖菙?shù)據(jù)存儲結(jié)構(gòu)是數(shù)組,故,parentlchildrchild存放的是相應(yīng)的下標(biāo)值,無需用指針來存儲。當(dāng)然,網(wǎng)上也有很多利用其二叉樹來實(shí)現(xiàn)的方法,由于自己還沒有達(dá)到那個高度,所以只好先用數(shù)組來實(shí)現(xiàn)了,慢慢來,慢慢提高,慢慢的接近大神。

在這個結(jié)構(gòu)體中,還定義了一個結(jié)構(gòu)體的構(gòu)造函數(shù),與“<”運(yùn)算符的函數(shù)。這樣便于對結(jié)構(gòu)體賦值及比較。稍后,為大家?guī)碓敿?xì)的講解。

其次,來看實(shí)現(xiàn)編碼的函數(shù)。

void HuffmanCoding( HuffmanTree &HT,HuffmanCode& HC,int *w,int n )

{

if (w==NULL || n<=1)

{

return;

}

if (HT!=NULL || HC !=NULL)

{

throw INVALID_PARAMETER;

return;

}

int m=2*n-1;

HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//從下標(biāo)開始計(jì)數(shù)

if (HT == NULL)

{

return;//是否還有什么工作沒有做

}

HuffmanTree p = HT;

*p=HTNode(0,0,0,0);

p++;

for (int i =1; i<=n; ++i,++p,++w)

{

*p=HTNode(*w,0,0,0);//利用結(jié)點(diǎn)的權(quán)值,初始化huffman樹的前n個結(jié)點(diǎn)。這就是用了結(jié)構(gòu)體的構(gòu)造函數(shù)好處,可以少寫很多的賦值代碼。

}

for(int i =n+1;i<=m;i++,++p)

{

*p=HTNode(0,0,0,0);//初始化huffman樹中的雙親節(jié)點(diǎn)。

}

unsigned int s1=0,s2=0;

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

{

//建立赫夫曼樹

SelectSubtree(HT,i-1,s1,s2);//可能有問題,如果函數(shù)中有異常的運(yùn)行情況怎么辦。

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*));//分配n個字符編碼的頭指針向量

char * cd =(char*)malloc(n*sizeof(char));

if (HC==NULL || cd ==NULL)

{

return ;//是否還有什么別的工作沒有做。

}

cd[n-1]='\0';

int start=0;

int c =0 ,f =0,len=0;

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

{

//逐個字符求赫夫曼編碼

start = n-1;

for (c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)

{

if (HT[f].lchild==c)

{

cd[--start]='0';

}

else

{

cd[--start]='1';

}

}

len = n-start;

HC[i] = (char *)malloc((len+1)*sizeof(char));//為第i個字符編碼分配空間

memset(HC[i],0,len+1);

strcpy_s(HC[i],len,&cd[start]);

}

free(cd);

}

注:1、要注意函數(shù)中,多處用了malloc動態(tài)的開辟內(nèi)存空間,要及時的對新開辟的內(nèi)存空間初始化。

2、要注意對開辟空間數(shù)據(jù)的操作,本人在對此指針操作的時候,多次造成指針越界,調(diào)試非常的痛苦,請朋友們一定要注意啦。如:strcpy_s函數(shù),開始由于沒有對cd開辟的空間做初始化為0的操作,造成了,函數(shù)多次彈出“buffer too small”的bug.

第三,HuffmanCoding函數(shù)中調(diào)用了一個SelectSubtree(...)函數(shù),當(dāng)然函數(shù)的定義如下,

void SelectSubtree( const HuffmanTree &HT,int limit,unsigned int & s1,unsigned int& s2 )

{

if (HT == NULL || limit<=0)

{

throw INVALID_PARAMETER;//參數(shù)異常

}

unsigned int min_1 = 0,min_2 =0;

for (int i = 1;i<=limit;i++)

{

if (HT[i].parent!=0)

{

continue;

}

else if (min_1==0)

{

min_1=i;

}

else if (min_2 == 0)

{

if (HT[i]<HT[min_1])

{//這里就利用了結(jié)構(gòu)體中”<”運(yùn)算符的作用,是不是看得很直觀啊!

min_2=min_1;

min_1=i;

}

else

{

min_2=i;

}

}

else if (HT[i]<HT[min_1])

{

min_2=min_1;

min_1=i;

}

else if (HT[i]<HT[min_2])

{

min_2 = i;

}

}

s1=min_1;

s2=min_2;

}

好了,到此,今天的blog已接近尾聲了,希望能幫助到難看的游客朋友,如果,你發(fā)現(xiàn)了其中的不足,請您提出您的的寶貴建議,讓我們共同提高,共同進(jìn)步,本人的QQ1272725,當(dāng)然,要是你還有什么不明白的地方,也可以加本人的QQ聯(lián)系,或者留言,一起討論。謝謝……

總結(jié)

以上是生活随笔為你收集整理的huffman(赫夫曼编码)之C/C++实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。