哈夫曼算法_范文大全

哈夫曼算法

【范文精选】哈夫曼算法

【范文大全】哈夫曼算法

【专家解析】哈夫曼算法

【优秀范文】哈夫曼算法

问题一:哈夫曼压缩算法的内容是什么?

哈夫曼压缩算法编码是无损压缩当中最好的方法。它使用预先二进制描述来替换每个符号,长度由特殊符号出现的频率决定。常见的符号需要很少的位来表示,而不常见的符号需要很多为来表示。

哈夫曼算法在改变任何符号二进制编码引起少量密集表现方面是最佳的。然而,它并不处理符号的顺序和重复或序号的序列。

哈夫曼压缩算法之原理

我不打算探究哈夫曼编码的所有实际的细节,但基本的原理是为每个符号找到新的二进制表示,从而通常符号使用很少的位,不常见的符号使用较多的位。

简短的说,这个问题的解决方案是为了查找每个符号的通用程度,我们建立一个未压缩数据的柱状图;通过递归拆分这个柱状图为两部分来创建一个二叉树,每个递归的一半应该和另一半具有同样的权(权是∑NK =1符号数k, N是分之中符号的数量,符号数k是符号k出现的次数)

这棵树有两个目的:

1. 编码器使用这棵树来找到每个符号最优的表示方法

2. 解码器使用这棵树唯一的标识在压缩流中每个编码的开始和结束,其通过在读压缩数据位的时候自顶向底的遍历树,选择基于数据流中的每个独立位的分支,一旦一个到达叶子节点,解码器知道一个完整的编码已经读出来了。

哈夫曼编码器生成哈夫曼树

压缩后的数据流是24位(三个字节),原来是80位(10个字节)。当然,我应该存储哈夫曼树,这样解码器就能够解码出对应的压缩流了,这就使得该例子中的真正数据流比输入的流数据量大。这是相对较短的数据上的副作用。对于大数据量来说,上面的哈夫曼树就不占太多比例了

最终的压缩数据流

解码的时候,从上到下遍历树,为压缩的流选择从左/右分支,每次碰到一个叶子节点的时候,就可以将对应的字节写到解压输出流中,然后再从根开始遍历。

哈夫曼压缩算法之实现

哈夫曼编码器可以在基本压缩库中找到,其是非常直接的实现。

这个实现的基本缺陷是:

1. 慢位流实现

2. 相当慢的解码(比编码慢)

3. 最大搐树深度是32(编码器在任何超过32位大小的时候退出)。如果我不是搞错的话,这是不可能的,除非输出的数据大于232字节。

另一方面,这个实现有几个优点:

1. 哈夫曼树以一个紧密的形式每个符号要求12位(对于8位的符号)的方式存储,这意味着最大的头为384。

2. 编码相当容易理解

哈夫曼编码在数据有噪音的情况(不是有规律的,例如RLE)下非常好,这中情况下大多数基于字典方式的编码器都有问题。

以上就是对哈夫曼压缩算法的简单介绍。

另外百度文库也有《哈夫曼压缩算法》你可以看参考资料

希望对您有帮助

参考资料:wenku.baidu.com/...9.html

问题二:哈夫曼算法与霍夫曼算法一样吗?

一样,都是Huffman

问题三:哈夫曼树的构造算法 5分

/*------------------------------------------------------------------------- * Name: 哈夫曼编码源代码。 * Date: 2011.04.16 * Author: Jeffrey Hill+Jezze(解码部分) * 在 Win-TC 下测试通过 * 实现过程:着先通过 HuffmanTree() 函数构造哈夫曼树,然后在主函数 main()中 * 自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在 * 父结点左侧,则置码为 0,若在右侧,则置码为 1。最后输出生成的编码。 *------------------------------------------------------------------------*/#include #include #define MAXBIT 100#define MAXVALUE 10000#define MAXLEAF 30#define MAXNODE MAXLEAF*2 -1 typedef struct { int bit[MAXBIT]; int start;} HCodeType; /* 编码结构体 */typedef struct{ int weight; int parent; int lchild; int rchild; int value;} HNodeType; /* 结点结构体 */ /* 构造一颗哈夫曼树 */void HuffmanTree (HNodeType HuffNode[MAXNODE], int n){ /* i、j: 循环变量,m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值, x1、x2:构造哈夫曼树不同过程中两个最小权值结点在数组中的序号。*/ int i, j, m1, m2, x1, x2; /* 初始化存放哈夫曼树数组 HuffNode[] 中的结点 */ for (i=0; i<2*n-1; i++) { HuffNode[i].weight = 0;//权值 HuffNode[i].parent =-1; HuffNode[i].lchild =-1; HuffNode[i].rchild =-1; HuffNode[i].value=i; //实际值,可根据情况替换为字母 } /* end for */ /* 输入 n 个叶子结点的权值 */ for (i=0; i>

问题四:哈夫曼编码的算法代码

// 哈夫曼编码(算法)#include

#include

#include typedef char *HuffmanCode; //动态分配数组,存储哈夫曼编码typedef struct

{

unsigned int weight; //用来存放各个结点的权值

unsigned int parent,LChild,RChild; //指向双亲、孩子结点的指针

} HTNode, *HuffmanTree; //动态分配数组,存储哈夫曼树//选择两个parent为0,且weight最小的结点s1和s2

void Select(HuffmanTree *ht,int n,int *s1,int *s2)

{

int i,min;

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

{

if((*ht)[i].parent==0)

{

min=i;

break;

}

}

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

{

if((*ht)[i].parent==0)

{

if((*ht)[i].weight<(*ht)[min].weight)

min=i;

}

}

*s1=min;

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

{

if((*ht)[i].parent==0 && i!=(*s1))

{

min=i;

break;

}

}

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

{

if((*ht)[i].parent==0 && i!=(*s1))

{

if((*ht)[i].weight<(*ht)[min].weight)

min=i;

}

}

*s2=min;

}//构造哈夫曼树ht。w存放已知的n个权值

void CrtHuffmanTree(HuffmanTree *ht,int *w,int n)

{

int m,i,s1,s2;

m=2*n-1;

*ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode));

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;

} 绩/非叶子结点初始化

printf("\nHuffmanTree: \n");

for(i=n+1; i<=m; i++) //创建非叶子结点......余下全文>>

问题五:哈夫曼译码算法

C++的

#include

#include

#include

#include

ofstream outstuf;

#define MAXBIT 50 // 哈夫曼编码的最大长度

#define M绩XVALUE 50 // 最大权值

#define MAXLEAF 50 // 哈夫曼树中叶子结点个数

#define MAXNODE MAXLEAF*2-1 //树中结点总数

//哈夫曼树结点结构

typedef struct

{

char data ; //结点值

int weight; //权值

int parent; //双亲结点

int lchild; //左孩子结点

int rchild; //右孩子结点

}HNodeType;

HNodeType HuffNode[MAXNODE];

//存放哈夫曼编码的数据元素结构

typedef struct

{

int bit [MAXBIT]; //存放哈夫曼码

int start; //编码的起始下标

}HCodeType;

void Haffmanfile(int n); //保存文件

HNodeType *HaffmanTree(int n) ; //构造哈夫曼树

void Haffmancode(int n); //构造哈夫曼编码

HNodeType *HaffmanTree(int n) //构造哈夫曼树

{

int i,j,m1,m2,x1,x2;

for(i=0;i<2*n-1;i++) //所有结点的初始化

{

HuffNode[i].weight=0;

HuffNode[i].parent=-1;

HuffNode[i].lchild=-1;

HuffNode[i].rchild=-1;

}

cout<<"\t________________________________________"<

cout<<"\t输入叶子结点的值和权值"<

cout<<"\t________________________________________"<

for(i=0;i

{

cout<<"\t______________________"<

cout<<"\t输入第......余下全文>>

问题六:哈夫曼树构造算法中j<n+i是什么意思

先看一下哈夫曼树的构造规则是:

假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:

(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);

(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;

(3)从森林中删除选取的两棵树,并将新树加入森林;

(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

用数据表示哈夫曼树的话,首先有n个权值点,其初始化就是从 0 到 n -1,先从这里面查找两个权值最小的结点,就是遍历一遍,把最小的值取出来。X1 和X2 要记录着两个权值在哪个位置。

然后把这两个权值加起来的和放回到数组n的位置,然后继续遍历这个数据,现在是从0 到n了,当然原来X1 和X2位置的两个点不用管,已经有父节点了。继续上述过程直到只有一个节点位置。

如 1 2 3 4 5 6构造哈夫曼树,先初始化parent 为 -1

1 2 3 4 5 6

parent -1 -1 -1 -1 -1 -1

先从上述中选取两个权值最小的节点 1 和 2,构造树变为3,放到数组6的位置,原权值序列变为:

1 2 3 4 5 6 3

parent 6 6 -1 -1 -1 -1 -1

继续选取 两个最小权值且parent为-1的点。找到3 和 3,放到数组7的位置,权值序列变为:

1 2 3 4 5 6 3 6

parent 6 6 7 -1 -1 -1 7 -1

继续选取 两个最小权值且parent为-1的点。找到4 和5,到数组8的位置,权值序列变为:

1 2 3 4 5 6 3 6 9

parent 6 6 7 8 8 -1 7 -1 -1

继续选取 两个最小权值且parent为-1的点。找到6 和6,到数组9的位置,权值序列变为:

1 2 3 4 5 6 3 6 9 12

parent 6 6 7 8 8 9 7 9 -1 -1

继续选取 两个最小权值且parent为-1的点。找到9 和12,到数组10的位置,权值序列变为:

1 2 3 4 5 6 3 6 9 12 21

parent 6 6 7 8 8 9 7 9 10 10 -1

结束

所以你说的j < n + i,由于每次选取两个权值的点权值和做为新的节点放在数组后面,当然下一次循环的时候要多一次循环。

X1 和X2要记录下选择两个权值,将其父节点的位置设置为新的权值点位置。

问题七:哈夫曼编码算法的实现

在网上看到一个,刚好用到,我试过的,正确

#include

#include

#include

#include

#include

using namespace std;

typedef struct {

unsigned int weight;

char ch1;

unsigned int parent,lchild,rchild;

}HTNode,*HuffmanTree;

typedef char **HuffmanCode;

typedef struct {

char ch;

char code[7];

}codenode,*code;

void select(HuffmanTree HT,int n,int & s1,int &s2){ //从哈夫曼树中选择出最小的两个节点

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

if(!HT[i].parent){

s1=i; break;

}

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

if(!HT[i].parent){

s2=i; break;

}

if(HT[s1].weight-HT[s2].weight){

int temp; temp=s1; s1=s2; s2=temp;

}

for(i=1;i<=n;i++) //对数组进行遍历,寻找最小的两个节点

if(!HT[i].parent){

if(HT[i].weight

s2=s1; s1=i;

}

else if(HT[i].weight

s2=i;

}

}

void prin(){ //终端输出选择菜单

cout<<"----------------------------------------------------\n\n"

<<" ∣ I---创建哈夫曼树 ∣\n"

<<" ∣ ∣\n"

<<" ∣ E---文件编码 ∣\n"

<<" ∣ ∣\n"

<<" ∣ D---文件译码 ∣\n"

<<" ∣ ∣\n"

<<" ∣ P---打印代码文件 ∣\n"

<<" ∣ ∣\n"

<<" ∣ T---印哈夫曼树 ∣\n"

<<" ∣ ∣\n"

<<" ∣ O---哈夫曼树的存储结构 ∣\n"

<<" ∣ ∣\n"

<<" ∣ Q---退出 ∣\n"

<<"\n----------------------------------......余下全文>>

问题八:哈夫曼编码 数据结构算法

#include

#include

#define N 50 /*叶子结点数*/

#define M 2*N-1 /*树中结点总数*/

typedef struct

{

char data[5]; /*结点值*/

int weight; /*权重*/

int parent; /*双亲结点*/

int lchild; /*左孩子结点*/

int rchild; /*右孩子结点*/

} HTNode;

typedef struct

{

char cd[N]; /*存放哈夫曼码*/

int start;

} HCode;

void CreateHT(HTNode ht[],int n)

{

int i,k,lnode,rnode;

int min1,min2;

for (i=0;i<2*n-1;i++) /*所有结点的相关域置初值-1*/

ht[i].parent=ht[i].lchild=ht[i].rchild=-1;

for (i=n;i<2*n-1;i++) /*构造哈夫曼树*/

{

min1=min2=32767; /*lnode和rnode为最小权重的两个结点位置*/

lnode=rnode=-1;

for (k=0;k<=i-1;k++)

if (ht[k].parent==-1) /*只在尚未构造二叉树的结点中查找*/

{

if (ht[k].weight

{

min2=min1;rnode=lnode;

min1=ht[k].weight;lnode=k;

}

else if (ht[k].weight

{

min2=ht[k].weight;rnode=k;

}

}

ht[lnode].parent=i;ht[rnode].parent=i;

ht[i].weight=ht[lnode].weight+ht[rnode].weight;

ht[i].lchild=lnode;ht[i].rchild=rnode;

}

}

void CreateHCode(HTNode ht[],HCode hcd[],int n)

{

int i,f,c;

HCode hc;

for (i=0;i

{

hc.start=n;c=i;

f=ht[i].parent;

while (f!=-1) /*循序直到树根结点*/

{

if (ht[f].lchild==c) /*处理左孩子结点*/

hc.cd[hc.start--]='0';

else /*处理右孩子结点*/

hc.cd[hc.start--]='1';

c=f;f=ht[f].parent;

}

hc.start++; /*start指向哈夫曼编码最开始字符*&#......余下全文>>

问题九:哈夫曼编码码长怎么算

假设用于通信的电文由字符集{a,b,c,d,e,f,g,h}中的字母构成,这8个字母在电文中出现的概率分别为{0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.10}. (1)为这8个字母设计哈夫曼编码。 (2)若用这三位二进制数(0…7)对这8个字母进行等长编码,则哈夫曼编码的平均码长是等长编码的百分之几?它使电文总长平均压缩多少? 解: (1)哈夫曼编码 根据上图可得编码表: a:1001 b:01 c:10111 d:1010 e:11 f:10110 g:00 h:1000 (2)用三位二进行数进行的等长编码平均长度为3,而根据哈夫曼树编码的平均码长为: 4*0.07+2*0.19+5*0.02+4*0.06+2*0.32+5*0.03+2*0.21+4*0.10=2.61 2.61/3=0.87=87% 其平均码长是等长码的87%。 所以平均压缩率为13%。 记得刚学哈夫曼树的时候还做过一道简单的题,好象是关于分数统计输入的,找不到题目了. 参考资料: 51zk.csai.cn/sjjg/200609041055411573.htm

求采纳

字典词典小学仪器室工作总结小学仪器室工作总结【范文精选】小学仪器室工作总结【专家解析】三国演义情节三国演义情节【范文精选】三国演义情节【专家解析】汉城奥运会金牌榜汉城奥运会金牌榜【范文精选】汉城奥运会金牌榜【专家解析】