数据结构试验-试验8-huffman树、huffman编码

huffman树又叫最优二叉树,关于huffman和huffman树的定义在这里就不再说了,网上有很多。这里讲下实现的过程,各种各样的方法有很多,这里只是其中的一种。

分为5个文件,huffman.h、huffman.cpp、drawtree.h、drawtree.cpp、HuffmanTestApp.cpp。下面一一说明下用途:

1、huffman.h是huffman树和编码的头文件:

#ifndef _HUFFMAN_H_
#define _HUFFMAN_H_

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

#define MAX_CODES  1000
#define MAX_WEIGHT 0x7FFFFFFF
#define LEFT_CODE	   '0'
#define RIGHT_CODE     '1'	

typedef struct 
{
	unsigned int weight;
	unsigned int parent, lchild, rchild;
}HTNode,*HuffmanTree;     
typedef struct
{
	char cd[MAX_CODES];	//这里本来是有别的信息的,后来删去了。		  
}HCode;
extern HCode hcd[MAX_CODES];			  
extern int Height;
extern int Hffuman_Nodes;
void BuildHuffmanTree(HuffmanTree& Hroot,int N,int* Message);
void Select(HuffmanTree& Hroot,int& x,int& y,int end);
void HuffmanCode(HuffmanTree& Hroot,char* code,int m,int k);
void FindHuffmanRoot(HuffmanTree& Hroot,int &k);

#endif //_HUFFMAN_H_
2、huffman.cpp文件是huffman.h的实现:
#include "Huffman.h"
int Height=0;
int Hffuman_Nodes=0;
HCode hcd[MAX_CODES];
void BuildHuffmanTree(HuffmanTree& Hroot,int N,int* Message)
{
	int x,y,j,i=N+1,k;
	char temp_code[1000]={0};
	Hffuman_Nodes=N;
	N=N*2;
	Hroot = (HuffmanTree)malloc(sizeof(HTNode)*N);
	memset(Hroot,0,sizeof(HTNode)*N);
	Hroot[0].weight = MAX_WEIGHT;
	for(j=1; j<i; j++)
		Hroot[j].weight = Message[j-1];
	while(i<N)
	{
		Select(Hroot,x,y,i);
		Hroot[x].parent = i;
		Hroot[y].parent = i;
		Hroot[i].lchild = x;
		Hroot[i].rchild = y;
		Hroot[i].weight=Hroot[x].weight+Hroot[y].weight;
		i++;
	}
	FindHuffmanRoot(Hroot,k);
	HuffmanCode(Hroot,temp_code,0,k);
	return ;
}
void Select(HuffmanTree& Hroot,int& x,int& y,int end)
{
	int i;
	x = y = 0;
	for(i=1; i<end; i++)
	{
		if(Hroot[i].parent) continue;
		if(Hroot[i].weight<Hroot[x].weight)
		{
			y = x;
			x = i;
		}
		else if(Hroot[i].weight<Hroot[y].weight)
		{
			y = i;
		}
	}
	return ;
}
void HuffmanCode(HuffmanTree& Hroot,char* code,int m,int k)
{
	if(k==0) return ;
	if(m>Height) Height=m;
	if(!Hroot[k].lchild&&!Hroot[k].rchild)
	{
		code[m]=0;
		strcpy(hcd[k].cd,code);
	}
	else
	{	
		code[m]=LEFT_CODE;

		HuffmanCode(Hroot,code,m+1,Hroot[k].lchild);

		code[m]=RIGHT_CODE;
		HuffmanCode(Hroot,code,m+1,Hroot[k].rchild);
	}
	return ;
}
void FindHuffmanRoot(HuffmanTree& Hroot,int &k)
{
	for(k=1; ; k++)
		if(!Hroot[k].parent)
			break;
	return ;
}
3、drawtree.h文件是图形相关文件,用于实现图形的:
#ifndef _DRAWTREE_H_
#define _DRAWTREE_H_
#include <stdio.h>
#include "graphics.h"
#include "Huffman.h"
#define DNodeRadius 30
#define DYoffset    NodeRadius*3
#define NodeShape  0
#define Codeoffset 60
#define LineThickNess 2
#define TreeLeafColor BLUE
#define TreeBackColor WHITE
#define Win_Width	  880
#define Win_Height	  600

extern  int NodeRadius;
extern  int Yoffset;
void Draw(HuffmanTree& Hroot);
void DrawNode(HuffmanTree& Hroot,int x,int y,int k);
void DrawHuffmanTree(HuffmanTree& Hroot,int x,int y,int len,int k);
void ScanHuffmanCode(HuffmanTree& Hroot);
#endif //_DRAWTREE_H_
4、drawtree.cpp文件是drawtree.h的实现:
#include "DrawTree.h"
int NodeRadius=DNodeRadius,Yoffset=DYoffset;
void Draw(HuffmanTree& Hroot)
{
	int k;
	initgraph(Win_Width,Win_Height);
	setcaption("Huffman Tree");
	setbkcolor(WHITE);
	line(Codeoffset,0,Codeoffset,Win_Height);
	setcolor(GREEN);
	outtextxy(Codeoffset+2,0,"Huffman Tree:");
	setlinestyle(1,NULL,LineThickNess);
	setbkmode(TRANSPARENT);
	FindHuffmanRoot(Hroot,k);
	if(Yoffset*(Height+1)>Win_Height)
		Yoffset=Win_Height/(Height+1);
	if((NodeRadius+2)*(1<<Height)*2>Win_Width-Codeoffset)
		NodeRadius = (Win_Width-Codeoffset)/(1<<Height+1)-2;
	if(Yoffset<0) Yoffset=1;
	if(NodeRadius<0) NodeRadius=0; 
	DrawHuffmanTree(Hroot,getwidth()/2+Codeoffset/2,NodeRadius+10,(NodeRadius+2)*(1<<Height),k);
}
void DrawNode(HuffmanTree& Hroot,int x,int y,int k)
{
	char temp_str[MAX_CODES];
	setcolor(RED);
	sprintf(temp_str,"%d",Hroot[k].weight);
	if(!Hroot[k].lchild&&!Hroot[k].rchild)
	   setfillcolor(TreeLeafColor);
	else
	   setfillcolor(TreeBackColor);
	switch(NodeShape)
	{
		case 0:
			fillellipse(x,y,NodeRadius,NodeRadius);
			outtextxy(x-strlen(temp_str)*4,y-8,temp_str);
			setcolor(GREEN);
			circle(x,y,NodeRadius); break;
		case 1:
			bar(x-NodeRadius,y-NodeRadius,x+NodeRadius,y+NodeRadius);
			outtextxy(x-strlen(temp_str)*4,y-8,temp_str);
			setcolor(GREEN);
			rectangle(x-NodeRadius,y-NodeRadius,x+NodeRadius,y+NodeRadius);
			break;
	}
}
void DrawHuffmanTree(HuffmanTree& Hroot,int x,int y,int len,int k)
{
	if(!k) return;
	len = len/2;
	DrawNode(Hroot,x,y,k);
	if(Hroot[k].lchild)
	{
		line(x,y+NodeRadius,x-len,y+Yoffset-NodeRadius);
		DrawHuffmanTree(Hroot,x-len,y+Yoffset,len,Hroot[k].lchild);
	}
	if(Hroot[k].rchild)
	{
		line(x,y+NodeRadius,x+len,y+Yoffset-NodeRadius);
		DrawHuffmanTree(Hroot,x+len,y+Yoffset,len,Hroot[k].rchild);
	}
}
void ScanHuffmanCode(HuffmanTree& Hroot)
{
	int i;
	char temp_str[30];
	outtextxy(0,0,"Code:");
	for(i=1; i<=Hffuman_Nodes; i++)
	{
		sprintf(temp_str,"%2d: %s",i,hcd[i].cd);
		outtextxy(0,20*i,temp_str);
	}
}
5、HuffmanTestApp.cpp文件,实现测试功能:
#include <stdio.h>
#include <math.h>
#include "Huffman.h"
#include "DrawTree.h"
int main()
{
	int n=6,weight[50]={1,2,3,4,5,6};
	HuffmanTree h;					//define huffman tree
	BuildHuffmanTree(h,n,weight);	//build tree
	Draw(h);						//draw huffman tree
	ScanHuffmanCode(h);				//scan Huffman code
	getch();
	return 0;
}

第一次运行会绘出一个测试huffman树,如下:

huffman tree

程序包可以在这下载:http://download.csdn.net/detail/decting/4793815

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值