05-树9 Huffman Codes (30分) 【C语言】

代码参考:https://blog.csdn.net/u011386173/article/details/95651745

题目:05-树9 Huffman Codes (30分)

算法分析

最优编码要求:

  • WPL值最小
  • 无歧义解码

问题总结

  • 最小堆使用数组存储,Huffman Tree结点使用链表存储怎样将二者建立联系?

  • 答:最小堆中的数组可以存储Huffman Tree结点的地址,也就是建立指针数组

代码

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
typedef struct{
	 char Character;
	 int Frequency;
}Node;
typedef struct TreeNode *HuffmanTree;
typedef HuffmanTree ElementType;
typedef struct HNode *MinHeap; 
struct HNode {
	ElementType *Data; 
	int Size;         
	int Capacity;     
};
struct TreeNode{
	int Weight;
	HuffmanTree Left,Right;
};
MinHeap CreateHeap( int MaxSize );
HuffmanTree CreateHuff();
bool IsFull( MinHeap H );
bool Insert( MinHeap H, ElementType X );
bool IsEmpty( MinHeap H );
ElementType DeleteMin( MinHeap H );
HuffmanTree Huffman(MinHeap H);
int WPL(HuffmanTree T,int Depth);
void ReadData(MinHeap H,Node Array[]);
int main()
{
	int N;
	scanf("%d",&N);
	Node Array[N];
	{
		int i;
		for(i=0;i<N;i++){
			getchar();
			scanf("%c %d",&Array[i].Character,&Array[i].Frequency);
		}
	}
	/*建堆*/
	MinHeap H=CreateHeap(N);
	/*把频数存入堆中*/ 
	ReadData(H,Array);
	/*先把堆整理为最小堆,然后再把最小堆整理为Huffman Tree*/
	HuffmanTree T=Huffman(H);
	/*计算Huffman Tree的WPL*/
	int CodeLen=WPL(T,0);
	/*
	1、计算出一个学生测试数据的实际WPL
	2、根据学生的测试数据构建一颗新的普通树,建树过程中标记每行数据的叶结点,检查叶节点是否是叶结点 
	*/ 
	int M;
	scanf("%d",&M);
	int i;
	for(i=0;i<M;i++){
		int sum=0; 
		int flag=1; 
		HuffmanTree Root=CreateHuff(); 
		HuffmanTree touch; 
		char c;
		char s[63]="\0";
		int j;
		for(j=0;j<N;j++){
			getchar();
			scanf("%c %s",&c,&s);
			int sl=strlen(s);
			sum+=sl*(Array[j].Frequency);
			if(flag==0)continue;
			touch=Root;
			int k=0; 
			for(k=0;k<sl;k++){
				if(s[k]=='0'){
					if(touch->Left==NULL){
						touch->Left=CreateHuff();
					}else{
						if(touch->Left->Weight==1){
							flag=0;
							break;
						}
					}
					touch=touch->Left;
				}else if(s[k]=='1'){
					if(touch->Right==NULL){
						touch->Right=CreateHuff();
					}else{
						if(touch->Right->Weight==1){
							flag=0;
							break;
						}
					}
					touch=touch->Right;
				}
				if(k==sl-1){
					touch->Weight=1;
					if(touch->Left||touch->Right){
						flag=0;
					}
				}
			}
		}
				if(flag==1&&sum==CodeLen){
					printf("Yes\n");
				}else{
					printf("No\n");
				}
	}
	return 0;
}
MinHeap CreateHeap( int MaxSize )
{ 
	MinHeap H = (MinHeap)malloc(sizeof(struct HNode));
	H->Data = (ElementType *)malloc((MaxSize+1)*sizeof(ElementType));
	H->Size = 0;
	H->Capacity = MaxSize;
	H->Data[0] = CreateHuff();
return H;
}
HuffmanTree CreateHuff()
{
	 HuffmanTree T=(HuffmanTree)malloc(sizeof(struct TreeNode));
	 T->Weight=0;
	 T->Left=NULL;
	 T->Right=NULL;
	 return T;
 } 
bool IsFull( MinHeap H )
{
    	return (H->Size == H->Capacity);
}
bool Insert( MinHeap H, ElementType X )
{ 
    int i;
    if ( IsFull(H) ) { 
        printf("最小堆已满");
        return false;
    }
    i = ++H->Size; 
    for ( ; H->Data[i/2]->Weight > X->Weight; i/=2 )
        H->Data[i] = H->Data[i/2]; 
    H->Data[i] = X; 
    return true;
}
bool IsEmpty( MinHeap H )
{
    return (H->Size == 0);
}
ElementType DeleteMin( MinHeap H )
{ 
	   int Parent, Child;
	   ElementType MinItem, X;
	   if ( IsEmpty(H) ) {
	       printf("最小堆已为空");
	       return NULL;
	   }
	   MinItem = H->Data[1]; 
	   X = H->Data[H->Size--]; 
	   for( Parent=1; Parent*2<=H->Size; Parent=Child ) {
	       Child = Parent * 2;
	       if( (Child!=H->Size) && (H->Data[Child]->Weight>H->Data[Child+1]->Weight) )
	           Child++;  
	       if( X->Weight <= H->Data[Child]->Weight ) break;
	       else H->Data[Parent] = H->Data[Child];
	   }
	   H->Data[Parent] = X;
	   return MinItem;
} 
HuffmanTree Huffman(MinHeap H)
{
	 int i;
	 HuffmanTree T;
	 int times=H->Size;
	 for(i=1;i<times;i++){
		  T=(HuffmanTree)malloc(sizeof(struct TreeNode));
		  T->Left=DeleteMin(H);
		  T->Right=DeleteMin(H);
		  T->Weight=T->Left->Weight+T->Right->Weight;
		  Insert(H,T);
	 }
	 T=DeleteMin(H);
	 return T;
}
int WPL(HuffmanTree T,int Depth)
{
	 if(!T->Left&&!T->Right){
	 	return (Depth*T->Weight);
	 }else{
	  	return (WPL(T->Left,Depth+1)+WPL(T->Right,Depth+1));
	 }
}
void ReadData(MinHeap H,Node Array[])
{
	 int i;
	 for(i=0;i<H->Capacity;i++){
		  HuffmanTree t=CreateHuff();
		  t->Weight=Array[i].Frequency;
		  Insert(H,t);
 	 }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值