作业十一

1.问题
给定字符集C={x1,x2,…,xn}和每个字符的频率f(x1),求关于C的一个最优前缀码
2.解析
构造最优前缀码的贪心算法就是霍夫曼算法。
霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。
3.设计
pnode HuffmanTree(int *mark, struct node *huffman, int size)
{
int choose[2];
int i;
pnode mynode;
for(i = 0; i < size-1; i++)
{
Select(mark, huffman, size, choose);
mynode = (pnode)malloc(sizeof(struct node));
mynode->key = huffman[choose[0]].key+huffman[choose[1]].key;//更新key值
mynode->l = (pnode)malloc(sizeof(struct node));
mynode->l->key = huffman[choose[0]].key;
mynode->l->l = huffman[choose[0]].l;
mynode->l->r = huffman[choose[0]].r;
mynode->r = &huffman[choose[1]];
huffman[choose[0]] = *mynode;
mark[choose[1]] = 0;
free(mynode);
}
return &huffman[choose[0]];
}
4.分析
O(nlogn)
5.源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
int key;
struct node *l;
struct node *r;
};
typedef struct node *pnode;
int mark[100];
struct node huffman[100];
void PrintNode(const pnode node)
{
printf(“key = %d \n”, node->key);
}
void PreOrder(pnode T)
{
if(T)
{
PrintNode(T);
PreOrder(T->l);
PreOrder(T->r);
}
}
void Select(int *mark, struct node *huffman, int size, int *choose)
{

int i;
for(i = 0;  i< size;  i++)
{
    if(mark[i])
    {
        choose[0] = i;
        i++;
        break;
    }
}
choose[1] = choose[0];
for(; i < size; i++)
{
    if(mark[i])
    {
        if(huffman[choose[0]].key >= huffman[i].key)
        {
            choose[1] = choose[0];
            choose[0] = i;
        }
        else if(huffman[choose[1]].key > huffman[i].key)
        {
            choose[1] = i;
        }
    }

}

}
void Choose(int *mark, struct node *huffman, int size, int *choose)
{
int i;
int minkey = 0;
int tkey = 0;
int temp = 0;
for(i = 0; i< size; i++)
{
if(mark[i])
{
minkey = i;
i++;
break;
}
}
tkey = minkey;
for(; i< size; i++)
{
if(mark[i])
{
if(huffman[i].key < huffman[minkey].key)
{
tkey = minkey;
minkey = i;
}
if(tkey == minkey)
tkey = i;
if(huffman[tkey].key > huffman[i].key && i != minkey)
{
tkey = i;
}
}
}
choose[0] = minkey;
choose[1] = tkey;
}
pnode HuffmanTree(int *mark, struct node *huffman, int size)
{
int choose[2];
int i;
pnode mynode;
for(i = 0; i < size-1; i++)
{
Select(mark, huffman, size, choose);
mynode = (pnode)malloc(sizeof(struct node));
mynode->key = huffman[choose[0]].key+huffman[choose[1]].key;//更新key值
mynode->l = (pnode)malloc(sizeof(struct node));
mynode->l->key = huffman[choose[0]].key;
mynode->l->l = huffman[choose[0]].l;
mynode->l->r = huffman[choose[0]].r;
mynode->r = &huffman[choose[1]];
huffman[choose[0]] = *mynode;
mark[choose[1]] = 0;
free(mynode);
}
return &huffman[choose[0]];
}
int main(void)
{
int key[8] = {5,29,7,8,14,23,3,11};
int i;
pnode huffmantree;
memset(mark, -1, sizeof(mark));
memset(huffman, 0, sizeof(huffman));
for(i = 0; i < 8; i++)
{
huffman[i].key = key[i];
}
huffmantree = HuffmanTree(mark, huffman, 8);
PreOrder(huffmantree);
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值