05-树9 Huffman Codes (30 分)段错误求助

In 1953, David A. Huffman published his paper “A Method for the Construction of Minimum-Redundancy Codes”, and hence printed his name in the history of computer science. As a professor who gives the final exam problem on Huffman codes, I am encountering a big problem: the Huffman codes are NOT unique. For example, given a string “aaaxuaxz”, we can observe that the frequencies of the characters ‘a’, ‘x’, ‘u’ and ‘z’ are 4, 2, 1 and 1, respectively. We may either encode the symbols as {‘a’=0, ‘x’=10, ‘u’=110, ‘z’=111}, or in another way as {‘a’=1, ‘x’=01, ‘u’=001, ‘z’=000}, both compress the string into 14 bits. Another set of code can be given as {‘a’=0, ‘x’=11, ‘u’=100, ‘z’=101}, but {‘a’=0, ‘x’=01, ‘u’=011, ‘z’=001} is NOT correct since “aaaxuaxz” and “aazuaxax” can both be decoded from the code 00001011001001. The students are submitting all kinds of codes, and I need a computer program to help me determine which ones are correct and which ones are not.

Input Specification:
Each input file contains one test case. For each case, the first line gives an integer N (2≤N≤63), then followed by a line that contains all the N distinct characters and their frequencies in the following format:

c[1] f[1] c[2] f[2] … c[N] f[N]
where c[i] is a character chosen from {‘0’ - ‘9’, ‘a’ - ‘z’, ‘A’ - ‘Z’, ‘_’}, and f[i] is the frequency of c[i] and is an integer no more than 1000. The next line gives a positive integer M (≤1000), then followed by M student submissions. Each student submission consists of N lines, each in the format:

c[i] code[i]
where c[i] is the i-th character and code[i] is an non-empty string of no more than 63 '0’s and '1’s.

Output Specification:
For each test case, print in each line either “Yes” if the student’s submission is correct, or “No” if not.

Note: The optimal solution is not necessarily generated by Huffman algorithm. Any prefix code with code length being optimal is considered correct.

Sample Input:
7
A 1 B 1 C 1 D 3 E 3 F 6 G 6
4
A 00000
B 00001
C 0001
D 001
E 01
F 10
G 11
A 01010
B 01011
C 0100
D 011
E 10
F 11
G 00
A 000
B 001
C 010
D 011
E 100
F 101
G 110
A 00000
B 00001
C 0001
D 001
E 00
F 10
G 11
Sample Output:
Yes
Yes
No
No

自己运行是没问题的,但是提交pat就是段错误……

# include <stdio.h>
# include <stdlib.h>
# include <string.h>

# define MAXSIZE 64 
# define MINDATA -1
typedef struct _heap* Heap;
typedef struct _tree* Tree;
struct _heap{
	Tree* freq; 
	//int* element;
	int size;
	int capacity;
};
struct _tree{
	int frequency;
	Tree left;
	Tree right;
};
int judge(int n,char cc,char code[],char* c,int* f,Tree t);
Tree checktree(Tree t,int i,char code[],int weight);
Heap readdata(int n,char* c,int* f);
int WPL(Tree t,int level);
Heap createheap(int maxsize);
Tree createtree(Tree t);
Tree buildhuffman(Heap h);
Tree deleteheap(Heap h);
void insertheap(Heap h,Tree t);
Heap buildheap(Heap h);
void freetree(Tree t);

void printheap(Heap h);
void PrintHuffman(Tree HT);

int len,codelen;
int main()
{
	int n,m,i,j,flag,*f;
	char *c,cc,code[64];
	Heap h;
	Tree huffmant,t;
	scanf("%d\n",&n);
	c=(char*)malloc(sizeof(char)*(n+1));
	f=(int*)malloc(sizeof(int)*(n+1));
	h=readdata(n,c,f);
	h=buildheap(h);
	huffmant=buildhuffman(h);
	len=WPL(huffmant,0);
	scanf("%d",&m);	
	for (j=1;j<=m;j++)
	{
		flag=1;
		t=createtree(t);
		t->frequency=0;
		codelen=0;
		for (i=1;i<=n;i++)
		{
			scanf("\n%c %s",&cc,code);
			if (flag) flag=judge(n,cc,code,c,f,t);
		}
		if (t) freetree(t);
		if (codelen!=len) flag=0;
		if (flag) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}
void printheap(Heap h)
{
	int i;
	for (i=1;i<=h->size;i++)
	  printf("%d %d\n",i,h->freq[i]->frequency);
}
void PrintHuffman(Tree HT)
{
    if(HT) {printf("%d ", HT->frequency);
         PrintHuffman(HT->left);
         PrintHuffman(HT->right);
       
  }
}
void freetree(Tree t)
{
	if (t->left) freetree(t->left);
	if (t->right) freetree(t->right);
	free(t);
}
int judge(int n,char cc,char code[],char* c,int* f,Tree t)
{
	int i,freq,weight=strlen(code);
	if (weight>n) return 0;
	for (i=1;i<=n;i++)
		if (c[i]==cc) break;		
	freq=f[i];
	codelen+=strlen(code)*freq;
	if (i>n) return 0;
	t=checktree(t,0,code,weight);
	//PrintHuffman(t);printf("\n");
	if (!t) return 0;
	else return 1;
}
Tree checktree(Tree t,int i,char code[],int weight)
{//printf("checktree:i=%d weight=%d\n",i,weight);
	if (i==weight)
	{//有weight条边,所以要访问weight+1个结点,即从0到weight,而非从0到weight-1!!! 
		if (!t)
		{
			t=createtree(t);
			t->frequency=1; //此处frequency=1表示该点已经有code,=0表示该点没有code 
		}
		else
		{
			if (!t->left && !t->right) t->frequency=1;
			else return NULL;
		}
	}
	if (i<=weight-1)
	{
		if (!t)
		{
			t=createtree(t);
			t->frequency=0;
			if (code[i]=='0')
			{
				t->left=checktree(t->left,i+1,code,weight);
				if (t->left==NULL) t=NULL;
			}
			else
			{
				t->right=checktree(t->right,i+1,code,weight);
				if (t->right==NULL) t=NULL;
			}
		}
		else
		{
			if (t->frequency) return NULL;
			else
			{
				if (code[i]=='0')
				{
					t->left=checktree(t->left,i+1,code,weight);
					if (t->left==NULL) t=NULL;
				}
				else
				{
					t->right=checktree(t->right,i+1,code,weight);
					if (t->right==NULL) t=NULL;
				}
			}
		}
	}
	return t;
}
Heap readdata(int n,char* c,int* f)
{
	int i;
	Heap h;
	h=createheap(n);
	h->size=n;
 
	for (i=1;i<=h->size;i++)
	{
		if (i==1) scanf("%c %d",&c[i],&f[i]);
		else scanf(" %c %d",&c[i],&f[i]);
		//printf("%d %c %d\n",i,c[i],f[i]);
		h->freq[i]=(Tree)malloc(sizeof(struct _tree)); 
		h->freq[i]->frequency=f[i];
		h->freq[i]->left=NULL;
		h->freq[i]->right=NULL;
	}
	return h;
}
int WPL(Tree t,int level)
{//printf("%d %d\n",t->left,t->right);
	if (!t->left && !t->right) return (t->frequency*level);
	else return (WPL(t->left,level+1)+WPL(t->right,level+1));
}
Heap createheap(int maxsize)
{
	Heap h;
	Tree t;
	h=(Heap)malloc(sizeof(struct _heap));
	h->freq=(Tree*)malloc(sizeof(int)*(maxsize+1));
	h->size=0;
	h->capacity=maxsize;
	t=createtree(t); //设立哨兵,注意哨兵是一个树结点!! 
	h->freq[0]=t;
	return h;
}
Tree createtree(Tree t)
{
	t=(Tree)malloc(sizeof(struct _tree));
	t->frequency=MINDATA;
	t->left=NULL;
	t->right=NULL;
}
Tree buildhuffman(Heap h)
{
	Tree t;
	while (h->size>=2)
	{//printf("%d\n",h->size); 
		t=(Tree)malloc(sizeof(struct _tree));
		t->left=deleteheap(h);
		t->right=deleteheap(h);
		t->frequency=t->left->frequency+t->right->frequency;
		insertheap(h,t);
	}
	t=deleteheap(h);
	return t;
}
Tree deleteheap(Heap h)
{
	int parent,child;
	Tree temp1,temp;
	if (h->size>0)
	{
		temp=h->freq[1];
		temp1=h->freq[h->size];
		h->size--;
		for (parent=1;parent*2<=h->size;parent=child)
		{
			child=parent*2;
			if (child+1<=h->size && h->freq[child]>h->freq[child+1])
			  child++;
			if (h->freq[child]->frequency < temp1->frequency)
			  h->freq[parent]=h->freq[child];//比较的是frequency,不要忘了,不能直接if h->freq[child] < temp1  
			else break;
		}
		h->freq[parent]=temp1;
	}
	return temp;
}
void insertheap(Heap h,Tree t)
{
	int i;
	for (i=++h->size;t->frequency<h->freq[i/2]->frequency;i=i/2)
		h->freq[i]=h->freq[i/2];
	h->freq[i]=t;
}
Heap buildheap(Heap h)
{
	int i,parent,child;
	Tree temp;
	for (i=h->size/2;i>=1;i--)
	{
		temp=h->freq[i];
		for (parent=i;parent<=h->size;parent=child)
		{
			child=parent*2;
			if (child+1<=h->size && h->freq[child]>h->freq[child+1])
				child++;
			if (h->freq[child]->frequency<temp->frequency)
			    h->freq[parent]=h->freq[child];
			else break;
		}
		h->freq[parent]=temp;
	}
	return h;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值