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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言赫夫曼树的编码与译码,哈夫曼树与编码译码实现

發(fā)布時(shí)間:2023/12/19 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言赫夫曼树的编码与译码,哈夫曼树与编码译码实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、哈弗曼樹的基本概念。

哈夫曼樹,又稱最優(yōu)樹,是一類帶權(quán)路徑長度最短的樹。下面有幾個(gè)概念:

(1)路徑。

樹中一個(gè)結(jié)點(diǎn)到另一個(gè)結(jié)點(diǎn)之間的分支構(gòu)成這兩個(gè)結(jié)點(diǎn)之間的路徑。

(2)路徑長度。

路徑上的分枝數(shù)目。

(3)樹的路徑長度。

從樹根到每一個(gè)結(jié)點(diǎn)的路徑長度之和。

(4)結(jié)點(diǎn)的帶權(quán)路徑長度。

從該結(jié)點(diǎn)到樹根之間的路徑長度與結(jié)點(diǎn)上權(quán)的乘積。

(5)樹的帶權(quán)路徑長度。

樹中所有葉子節(jié)點(diǎn)的帶權(quán)路徑長度之和。通常記作:

帶權(quán)路徑長度WPL最小的二叉樹叫做最優(yōu)二叉樹或哈夫曼樹。

二、構(gòu)造哈夫曼樹。

采用哈夫曼法算法構(gòu)造過程為:

(1)根據(jù)給定的n個(gè)權(quán)值{w1,w2,…,wn}構(gòu)成n棵二叉樹的集合F={T1,T2,…,Tn},其中每棵樹Ti中只有一個(gè)帶權(quán)為wi的根結(jié)點(diǎn),其左右子樹均空。

(2)在F中選取兩棵根結(jié)點(diǎn)的權(quán)值最小的樹作為左右子樹構(gòu)造一棵新的二叉樹,且置新的二叉樹的根結(jié)點(diǎn)的權(quán)值為其左、右子樹上根結(jié)點(diǎn)的權(quán)值之和。

(3)在F中刪除這兩棵樹,同時(shí)將新得到的二叉樹加入到F中。

(4)重復(fù)(2)和(3),直到F只含一棵樹為止。

例如權(quán)值為7,5,2,4的結(jié)點(diǎn)構(gòu)造過程為:

------------------------------分割線------------------------------

將C語言梳理一下,分布在以下10個(gè)章節(jié)中:

三、編碼和編碼樹。

1、等長編碼和不等長編碼。

(1)等長編碼。

每個(gè)字符的編碼長度相同(每個(gè)編碼所含的二進(jìn)制位數(shù)相同)。特點(diǎn)是編(譯)碼容易,抗干擾能力強(qiáng),但長度不是最短,效率低。

(2)不等長編碼。

與等長編碼相對,效率高。若要設(shè)計(jì)長短不等的編碼(考慮譯碼唯一性),則必須是任一個(gè)字符的編碼都不是另一個(gè)字符的編碼的前綴,這種編碼稱作前綴編碼。

2、哈夫曼編碼。

考慮利用二叉樹來設(shè)計(jì)二進(jìn)制的前綴編碼。約定左分支表示字符0,右分支表示字符1,從根結(jié)點(diǎn)到葉子結(jié)點(diǎn)的路徑上分支字符組成的字符串作為該葉子結(jié)點(diǎn)字符的編碼,可以證明得到的必為二進(jìn)制前綴碼。

考慮如何得到使電文長度最短的二進(jìn)制前綴編碼。可以看出,設(shè)計(jì)電文總長最短的二進(jìn)制前綴編碼即以n種字符出現(xiàn)的頻率作權(quán),構(gòu)造一顆哈夫曼樹。

下面給出C++參考代碼:

#include

#include

#include

#include

#include

using namespace std;

struct TNode

{

unsigned int weight;

unsigned int parent;

unsigned int lchild;

unsigned int rchild;

struct TNode() : weight(0), parent(0), lchild(0), rchild(0){}

};

class HuffTree

{

public:

void HuffmanCode(vector &HT, vector &HC, const vector &wgh);

void HuffDecodeing(vector &HT, vector &HC, vector &SrcCode);

private:

void InitHuffTree(vector &HT, const vector &wgh);

void BuildHuffTree(vector &HT, const vector &wgh);

void SelectTwoMin(vector &HT, int n, int &min1, int &min2);

void HuffCodeing(vector &HT, vector &HC, const vector &wgh);

};

void HuffTree::InitHuffTree(vector &HT, const vector &wgh)

{

if (wgh.empty())

{

return;

}

int wghSize = wgh.size();

int m = 2 * wghSize - 1;

HT.resize(m + 1);

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

{

HT[i].weight = wgh[i - 1];

}

}

void HuffTree::SelectTwoMin(vector &HT, int n, int &min1, int &min2)

{

if (HT.empty())

{

return;

}

multimap wghMap;

multimap::iterator iter;

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

{

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

{

wghMap.insert(make_pair(HT[i].weight, i));

}

}

if (wghMap.size() >= 2)

{

iter = wghMap.begin();

min1 = iter->second;

min2 = (++iter)->second;

}

}

void HuffTree::BuildHuffTree(vector &HT, const vector &wgh)

{

if (HT.empty() || wgh.empty())

{

return;

}

int htSize = HT.size();

int wghSize = wgh.size();

int wghs1, wghs2;

for (int i = wghSize + 1; i < htSize; i++)

{

SelectTwoMin(HT, i, wghs1, wghs2);

HT[wghs1].parent = i;

HT[wghs2].parent = i;

HT[i].lchild = wghs1;

HT[i].rchild = wghs2;

HT[i].weight = HT[wghs1].weight + HT[wghs2].weight;

}

}

void HuffTree::HuffCodeing(vector &HT, vector &HC, const vector &wgh)

{

if (HT.empty() || wgh.empty())

{

return;

}

int n = wgh.size() + 1;

int cha, par;

string codeTmp, code;

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

{

code.clear();

codeTmp.clear();

for (cha = i, par = HT[i].parent; par != 0; cha = par, par = HT[par].parent)

{

if (HT[par].lchild == cha)

{

codeTmp = codeTmp + "0";

}

else

{

codeTmp = codeTmp + "1";

}

}

for (int j = codeTmp.size() - 1; j >= 0; --j)

{

code = code + codeTmp[j];

}

HC.push_back(code);

}

}

void HuffTree::HuffDecodeing(vector &HT, vector &HC, vector &SrcCode)

{

if (HT.empty() || HC.empty())

{

return;

}

string codeTmp;

int p, strLen;

for (int i = 0; i < HC.size(); ++i)

{

p = HT.size() - 1;? ? ? ? ? ? ? ? ? ? ? ? //回到根結(jié)點(diǎn)

codeTmp = HC[i];

strLen = codeTmp.size();

for (int j = 0; j < strLen; ++j)

{

if (codeTmp[j] == '0')

{

p = HT[p].lchild;

}

else

{

p = HT[p].rchild;

}

}

SrcCode.push_back(HT[p].weight);

}

}

void HuffTree::HuffmanCode(vector &HT, vector &HC, const vector &wgh)

{

if (wgh.empty())

{

return;

}

InitHuffTree(HT, wgh);

BuildHuffTree(HT, wgh);

HuffCodeing(HT, HC, wgh);

}

總結(jié)

以上是生活随笔為你收集整理的c语言赫夫曼树的编码与译码,哈夫曼树与编码译码实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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