哈夫曼编码

#include "stdio.h"
#include "stdlib.h"
#define N 10
int A[2*N];//标志数组,用于Select函数
typedef struct {
	char value;
	int weight;
	int parent;
	int lchild;
	int rchild;
}HTNode;//HuffManTree结点
typedef struct HCNode{
	char value;
	struct HCNode *next;
}HCNode;//HC结点
int Select(HTNode *HT,int n,int *i,int *j){
	int k=1;
	for (k=1,*i=0; k<=n; k++){
		if(HT[k].weight <= HT[*i].weight)
			if(A[k] == 0)
				*i=k;
		if(k==n)
			A[*i]=1;
	}
	for (k=1,*j=0; k<=n; k++){
		if(HT[k].weight <= HT[*j].weight)
			if(A[k] == 0)
				*j=k;
		if(k==n)
			A[*j]=1;
	}
	return 1;
}
HuffManHC(HTNode * HT,HCNode * HC){
	int i,p,q;
	HCNode * HC1;
	for (i=1; i<=N; i++){
		p=i;
		HC[i].value=HT[i].value;
		while(HT[p].parent != 0){
			q=p;
			p=HT[p].parent;
			HC1=(HCNode *)malloc(sizeof(HCNode));
			if(HT[p].lchild == q)
				HC1->value='0';
			else HC1->value='1';
			HC1->next=HC[i].next;
			HC[i].next=HC1;
		}
	}
	for (i=1; i<=N; i++){//输出HuffMan编码所对应的数组型链表
		printf("%c: ",HC[i].value);
		HC1=HC[i].next;
		while(HC1){
			printf("%c",HC1->value);
			HC1=HC1->next;
		}
		printf("\n");
	}
}
int main () {
	char v;
	int i,j,k;
	HTNode *HT;
	HCNode *HC;
	int m=2*N-1;//总节点数目
	HT = (HTNode *) malloc ((m+1) * sizeof(HTNode));//0号单元不用
	for (i=0; i<m+1; i++) {
		HT[i].value='^';
		HT[i].weight=0;
		HT[i].parent=0;
		HT[i].lchild=0;
		HT[i].rchild=0;
	}//初始化HuffManTree
	for (i=1; v !='!'; i++){//输入字符,并用求对应权值,注意此程序限制叶子节点个数位N,字符常量
		v=getchar();
		for (j=1; j<=i; j++){//判断字符是否与先前输入相同
			if(v==HT[j].value && v!='!'){
				HT[j].weight += 1;//相同则权值+1
				i--;
				break;
			}
			if(i==j && v!='!'){
				HT[i].value=v;
				HT[i].weight=1;
			}
		}
	}
	for (i=0;i<m+1;i++)
		A[i]=0;//初始化标志数组
	HT[0].weight=100000;//鉴于Select函数特殊需要,避免了部分错误
	for(k=N+1; k<=m; k++){//建立完整HuffManTree
		Select(HT,k-1,&i,&j);//通过函数选择权值最小的两个结点,/HT为指针/
		HT[k].lchild=i;
		HT[k].rchild=j;
		HT[k].weight=HT[i].weight+HT[j].weight;
		HT[i].parent=k;
		HT[j].parent=k;
	}
	for (i=0; i<=m; i++)//输出数组表示法所建立的HuffManTree
		printf("%c %4d%4d%4d%4d\n",HT[i].value,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
	HC=(HCNode *)malloc((N+1)*sizeof(HCNode));
	for (i=0;i<=N;i++)//初始化HuffMan编码数组链表
		HC[i].next=NULL;
	HuffManHC(HT,HC);
	getchar();
	j=2*N-1;
	v=' ';
	for(; v!='!'; ){
		v=getchar();
		if(v=='0')
			j=HT[j].lchild;
		else if (v=='1')
			j=HT[j].rchild;
		else if(v!='!'){
			printf("ENTER ERROR1\n");
			exit(0);
		}
	}
	if(j>N)
		printf("ENTER ERROR2\n");
	if(0 < j &&  <= N)
		printf("%c\n",HT[j].value);
	if(j==0)
		printf("ENTER ERROR3\n");
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值