6-2 哈夫曼编码

函数Select (HuffmanTree HT,int len,int &s1,int &s2)是从1到len中找出parent为0的且权值最小的节点编号赋给s1,s2,(s1的节点编号小于s2),函数void CreatHuffmanTree(HuffmanTree &HT,int n)是构造哈夫曼树,函数void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)计算哈夫曼编码。

函数接口定义:

void Select(HuffmanTree HT,int len,int &s1,int &s2);
void CreatHuffmanTree(HuffmanTree &HT,int n);
void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n);

其中 HT 是哈夫曼树,HC是哈夫曼编码, n是叶子结点个数。

裁判测试程序样例:

#include <cstring>
#include<iostream>
using namespace std; 

typedef struct
{    char ch;
    int weight;
    int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char **HuffmanCode;
void Select(HuffmanTree HT,int len,int &s1,int &s2);
void CreatHuffmanTree(HuffmanTree &HT,int n);
void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n);
void show(HuffmanTree HT,HuffmanCode HC,int n);

int main()
{
    HuffmanTree HT;
    HuffmanCode HC;
    int n;
    cin >> n;
    CreatHuffmanTree(HT,n);
    CreatHuffmanCode(HT,HC,n);
    show(HT,HC,n);
    return 0;
}
void show(HuffmanTree HT,HuffmanCode HC,int n)
{
    for(int i=1;i<=n;i++)
        printf("%c:%s\n",HT[i].ch,HC[i]);
}

/* 请在这里填写答案 */

输入样例:

第一行输入一个数n(1<n<100),表示叶子节点的个数,接下去输入n行,每行输入一个字符和一个整数,表示每个节点表示的字符和权值。

5
A 8
B 10
C 2
D 11
E 1

输出样例:

输出n行,每行输出一个字符及其编码,字符与编码中“:”分隔。

A:01
B:10
C:001
D:11
E:000

答案代码: 

void Select(HuffmanTree HT,int len,int &s1,int &s2)
{
    int x1=0,x2=0;
    int m1=10000,m2=10000;
    for(int i=1;i<=len;i++)
    {
        if(HT[i].parent==0&&HT[i].weight<m1)
        {
            x2=x1;
            m2=m1;
            m1=HT[i].weight;
            x1=i;
        }
        else if(HT[i].parent==0&&HT[i].weight<m2)
        {
            x2=i;
            m2=HT[i].weight;
        }
    }
    s1=x1;
    s2=x2;
}


void CreatHuffmanTree(HuffmanTree& HT, int n)
{
    int s1=0;
    int s2=0;
    HT = (HuffmanTree)malloc(sizeof(HTNode)*(2*n));
    for (int i = 1; i <=n ; ++i) {
        cin>>HT[i].ch;
        cin>>HT[i].weight;
    }
    for (int i = 1;i<=2*n-1;i++) 
    {
    	HT[i].parent =0;
    	HT[i].lchild =0;
    	HT[i].rchild =0;
	}
	for (int i=n+1;i<=2*n-1;i++)
    {
		Select(HT,i-1,s1,s2);
		HT[i].lchild  =s1;
		HT[i].rchild  =s2;
		HT[s1].parent =i; 
	    HT[s2].parent =i;
		HT[i].weight =HT[s1].weight+HT[s2].weight ;
	}
}
void CreatHuffmanCode(HuffmanTree HT, HuffmanCode &HC, int n) {
	char tmp[n];
	tmp[n-1] = '\0';
	int start, c, f;
	for(int i = 1; i <= n; i++) {
		start = n - 1;
		c = i;
		f = HT[i].parent;
		while(f){
			if(HT[f].lchild == c)
				tmp[--start] = '0';
			else
				tmp[--start] = '1';
			c = f;
			f = HT[f].parent;
		}
		HC[i] = (char *)malloc((n-start)*sizeof(char));
		strcpy(HC[i], &tmp[start]);
	}
}

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值