哈夫曼树编码 c语言感悟,哈夫曼树编码C语言实现

实现哈夫曼树编码的算法可分为两大部分:

(1)构造哈夫曼树;

(2)在哈夫曼树上求叶结点的编码;

哈夫曼树构造算法:

(1)由给定的n个权值构造n棵只有一个叶结点的二叉树,从而得到一个二叉树的集合F={T1,T2,,...,TN}

(2)在F中选取根结点的权值最小和次小的两棵二叉树作为左,右子树构造一棵新的二叉树,这棵二叉树根结点的权值为其左右子树权值之和

(3)在集合F中删除作为左右子树的两棵二叉树,并将新建立的二叉树加入到集合F中

(4)重复(2)(3)直到F中只剩下最后一棵所需的二叉树,就是哈夫曼树

在哈夫曼树上求叶结点的编码算法:

在已建立的哈夫曼树中,从叶结点开始,沿结点的双亲链回退到根结点,每回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼的值

规定哈夫曼树中的左分支代表0,右分支代表1

举例:

A:5 B:29 C:7 D:8 E:14 F:23 G:3 H:11

哈夫曼树:

6961739b97cec10a80fe0f13b9e5d750.png

哈夫曼树的存储:

weight         parent   Lchild    Rchild

5

8

-1

-1

29

13

-1

-1

7

9

-1

-1

8

9

-1

-1

14

11

-1

-1

23

12

-1

-1

3

8

-1

-1

11

10

-1

-1

8

10

0

6

15

11

2

3

19

12

7

8

29

13

4

9

42

14

5

10

58

14

1

11

100

-1

12

13

源代码:

#include

#define n 8                                        //叶子结点数目

#define m (2*n-1)                                  //总结点数目,可证明

#define MAXVALUE 10000                             //最大权值

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

typedef struct

{

char ch;

int weight;

int parent;

int Lchild, Rchild;

}Htreetype;

typedef struct

{

int bit[n];                                   //位串

int start;                                    //编码在位串中的起始位置

char ch;

}Hcodetype;

void select(Htreetype t[], int k, int *p1, int *p2)  //选择权值最小的结点

{

*p1 = *p2 = 0;

int small1, small2;

small1 = small2 = MAXVALUE;

int i;

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

{

if (t[i].parent == -1)

{

if (t[i].weight < small1)

{

small2 = small1;

small1 = t[i].weight;

*p2 = *p1;

*p1 = i;

}

else if (t[i].weight < small2)

{

small2 = t[i].weight;

*p2 = i;

}

}

}

}

void HuffmanTree(Htreetype t[])                  //构造哈夫曼树

{

int i, j, p1, p2, f;

p1 = p2 = 0;

char c;

for (i = 0; i < m; i++)                       //初始化

{

t[i].weight = 0;

t[i].Lchild = -1;

t[i].parent = -1;

t[i].Rchild = -1;

}

printf("共有%d个字符\n", n);

for (i = 0; i < n; i++)                            //输入字符和对应的权值

{

printf("请输入第%d个字符和权值','分隔", i + 1);

scanf("%c,%d", &c,&f);

getchar();

t[i].ch = c;

t[i].weight = f;

}

for (i = n; i < m; i++)                            //构造哈夫曼树

{

select(t, i, &p1, &p2);

t[p1].parent = i;

t[p2].parent = i;

t[i].Lchild = p1;

t[i].Rchild = p2;

t[i].weight = t[p1].weight + t[p2].weight;

}

}

void HuffmanCode(Hcodetype code[],Htreetype t[])                                   //哈夫曼编码

{

int i, c, p;

Hcodetype cd;      //缓冲变量,暂时存储

HuffmanTree(t);

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

{

cd.start = n;

cd.ch = t[i].ch;

c = i;               //从叶子结点向上

p = t[i].parent;     //t[p]是t[i]的双亲

while (p != -1)

{

cd.start--;

if (t[p].Lchild == c)

cd.bit[cd.start] = '0';        //左子树编为0

else

cd.bit[cd.start] = '1';        //右子树编为1

c = p;                             //移动

p = t[c].parent;

}

code[i] = cd;                         //第i+1个字符的编码存入code

}

}

void show(Htreetype t[], Hcodetype code[])

{

int i, j;

for (i = 0; i

{

printf("%c: ", code[i].ch);

for (j = code[i].start; j

printf("%c ", code[i].bit[j]);

printf("\n");

}

}

void Print()

{

printf("戴尔XPS-15\n");

}

int main()

{

Htreetype t[m];

Hcodetype code[n];

HuffmanCode(code, t);

show(t,code);

return 0;

}

运行结果:

43bb7424fa5ecbda38028f1e05ae7376.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值