实验三.哈夫曼编码的贪心算法设计

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验四哈夫曼编码的贪心算法设计( 4 学时)

[实验目的]

1. 根据算法设计需要,掌握哈夫曼编码的二叉树结构表示方法;

2. 编程实现哈夫曼编译码器;

3. 掌握贪心算法的一般设计方法。

实验目的和要求

(1)了解前缀编码的概念,理解数据压缩的基本方法;

(2)掌握最优子结构性质的证明方法;

(3)掌握贪心法的设计思想并能熟练运用

(4)证明哈夫曼树满足最优子结构性质;

(5)设计贪心算法求解哈夫曼编码方案;

(6)设计测试数据,写出程序文档。

实验内容j

设需要编码的字符集为{d1, d2, -dn },它们出现的频率为k i a k{w1, w2, --wn},应用哈夫曼树构ki 造最短的不等长编码方案。

核心源代码

#include

#include

#include

typedef struct

{

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

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

} HTNode, *HuffmanTree;// 动态分配数组,存储哈夫曼树

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

可编辑

// 选择两个 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("\n 哈夫曼树为 : \n");

for(i=n+1; i<=m; i++) // 创建非叶子结点,建哈夫曼树

{ II在(*ht)[1]~(*ht)[i-1] 的范围内选择两个pare nt为0且weight最小的结点,其序号分别赋值给si、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;

printf("%d (%d, %d)\n",(*ht)[i].weight,(*ht)[s1].weight,(*ht)[s2].weight);

}

printf("\n");

}

// 从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码

void CrtHuffmanCode(HuffmanTree *ht, HuffmanCode *hc, int n)

{

char *cd; // 定义的存放编码的空间

int a[100];

int i,start,p,w=0;

unsigned int c;

hc=(HuffmanCode *)malloc((n+1)*sizeof(char *)); // 分配 n 个编码的头指针

cd=(char *)malloc(n*sizeof(char)); // 分配求当前编码的工作空间

cd[n-1]='\0'; // 从右向左逐位存放编码,首先存放编码结束符

for(i=1; i<=n; i++) // 求 n 个叶子结点对应的哈夫曼编码

{

a[i]=0;

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]='1'; // 左分支标 1

a[i]++;

}

else

{

相关文档
最新文档