數據結構集中實踐 哈夫曼樹實驗報告


 

二、實驗內容

1.根據給出的字符以及這些字符的使用頻率構建哈夫曼樹。

2.根據哈夫曼樹對字符進行哈夫曼編碼,並保存這些編碼。

三、實驗原理、方法和手段

     試構造出問題模型,並編程實現這一問題的求解。根據實驗內容編程,上機調試、得出正確的運行程序;編譯運行程序,觀察運行情況和輸出結果。

六、實驗步驟

1. 建立哈夫曼樹的存儲結構和哈夫曼編碼的存儲結構。

2. 建立哈夫曼樹的函數;

3. 哈夫曼編碼的函數;

4.哈夫曼編碼的解碼函數

5. 設計測試用例進行測試。

七、實驗報告

記錄數據結構與算法設計的過程及實驗步驟、上機過程中遇到的困難及解決辦法、遺留的問題、托福考位意見和建議等。格式見實驗報告模板。 測試數據及測試結果請在上交的資料中寫明。

                     #include <stdio.h>
#include <string.h>
#define N 50
#define M 2*N-1	
const int INF=1e9+7;
typedef struct//哈夫曼樹的存儲結構 
{
	char data[6];
	double weight;	
	int parent;	
	int lchild;		
	int rchild;		
} HTNode;
typedef struct//存放哈夫曼碼存儲結構 
{
	char cd[N];		
	int start;
} HCode;
void CreateHT(HTNode ht[],int n0)	//建立哈夫曼樹的函數 
{	
	int i,k,lnode,rnode;
	double min1,min2;
	for (i=0;i<2*n0-1;i++)		
		ht[i].parent=ht[i].lchild=ht[i].rchild=-1;
	for (i=n0;i<=2*n0-2;i++)		
	{	
		min1=min2=INF;//min1存最小的權值,min2存次小權值		
		lnode=rnode=-1;
		for (k=0;k<i;k++)//尋找ht里面未使用的最小的兩個數 
			if (ht[k].parent==-1) 
			{	
				if(ht[k].weight<min1)
				{	
					min2=min1;//保證min1<=min2 
					rnode=lnode;
					min1=ht[k].weight;
					lnode=k;
				}
				else if(ht[k].weight<min2)
				{	
					min2=ht[k].weight;
					rnode=k; 
				}
			}
		ht[i].weight=ht[lnode].weight+ht[rnode].weight;
		ht[i].lchild=lnode;
		ht[i].rchild=rnode;
		ht[lnode].parent=i;
		ht[rnode].parent=i;
	}
}

void CreateHCode(HTNode ht[],HCode hcd[],int n0)	//構造哈夫曼樹編碼
{	
	int i,f,c;
	HCode hc;
	for (i=0;i<n0;i++)			
	{	
		hc.start=n0;c=i;
		f=ht[i].parent;
		while (f!=-1)				
		{	
			if (ht[f].lchild==c)
				hc.cd[hc.start--]='0';
			else				
				hc.cd[hc.start--]='1';
			c=f;
			f=ht[f].parent;	
		}
		hc.start++;			
		hcd[i]=hc;
	}
}

void DispHCode(HTNode ht[],HCode hcd[],int n0) 
{
	int i,k,temp=0;
	double sum=0;
	int j;
	printf("  輸出");
	for(i=0;i<8;i++)
		printf("%s",ht[i].data);
	printf("的哈夫曼編碼:\n");
	for (i=0;i<n0;i++)
	{
		printf("    %s:\t\t",ht[i].data);
		for (k=hcd[i].start;k<=n0;k++)
			printf("%c",hcd[i].cd[k]);
		printf("\n"); 
	}	
}

void Decode(HTNode ht[],char code[]) //解碼 
{
	printf("\n\n  對“%s”解碼:\n",code);
	int p=ht[0].parent;
	int m;//根 
	while(p!=-1)//找到根 
	{
		m=p;
		p=ht[m].parent;	
	}
	int t;
	int a1=0,a2=0;
	for(int i=0;i<strlen(code);)
	{
		a1=a2;
		t=m;
		while(ht[t].lchild!=-1&&ht[t].rchild!=-1&&i<strlen(code)) 
		{
			if(code[i]== '0')                
				t=ht[t].lchild;           
			else  if(code[i]== '1')             
				t=ht[t].rchild;
			i++;			    
		}
		a2=i;
		if(t==-1||ht[t].lchild!=-1&&ht[t].rchild!=-1)
		{
			int j=i-1;
			printf("   ");
			for(int j=a1;j<a2;j++)
				printf("%c",code[j]);
			printf(":\t錯誤\n");
		} 	
		else
		{
			printf("   ");
			for(int j=a1;j<a2;j++)
				printf("%c",code[j]);
			printf(":%6s\n",ht[t].data);
		}			
	} 
	printf("\n");
}
int main()
{
	int n=8,i;		//n表示初始字符串的個數
	char str[][2]={"a","b","c","d","e","f","g","h"};
	double fnum[]={0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.1};
	char code[40];
	HTNode ht[M];//存哈夫曼樹 
	HCode hcd[N];//存哈夫曼編碼 
	for (i=0;i<n;i++) 
	{
		strcpy(ht[i].data,str[i]);
		ht[i].weight=fnum[i];
	}
	CreateHT(ht,n);
	CreateHCode(ht,hcd,n);
	DispHCode(ht,hcd,n);
	printf("\n");
	printf("  請輸入編碼:"); 
	scanf("%s",code);
	Decode(ht,code);
	return 1;
}  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM