⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 huffman.cpp

📁 哈夫曼方面的编程实例
💻 CPP
字号:
#include <iostream.h>
#include <stdlib.h>
const int MaxValue=10000;
const int MaxN = 10;
struct HaffNode
//哈夫曼树的结点结构
{
	char x;
	int weight;								//权值
	int flag;								//标记
	int parent;								//双亲结点下标
	int leftChild;							//左孩子下标
	int rightChild;							//右孩子下标
};

struct Code
//存放哈夫曼编码的数据元素结构
{
	char bit[MaxN];							//数组
	int start;								//编码的起始下标
	int weight;	                            //字符的权值
	char x;
};
//建立叶结点个数为n权值为weight的哈夫曼树haffTree

void Haffman(int n, HaffNode haffTree[])
{
	int j, m1, m2, x1, x2,i;//构造哈夫曼树haffTree的n-1个非叶结点
	for(i = 0;i < n-1;i++)
	{
		m1 = m2 = MaxValue;
		x1 = x2 = 0;
		for(j = 0; j < n+i;j++)
		{
			if(haffTree[j].weight < m1 && haffTree[j].flag == 0)
			{
				m2 = m1;
				x2 = x1;
				m1 = haffTree[j].weight;
				x1 = j;
			}
			else if(haffTree[j].weight < m2 && haffTree[j].flag == 0)
			{
				m2 = haffTree[j].weight;
				x2 = j;
			}
		}		//将找出的两棵权值最小的子树合并为一棵子树
		haffTree[x1].parent  = n+i;   
		haffTree[x2].parent  = n+i;
		haffTree[x1].flag    = 1;
		haffTree[x2].flag    = 1;
		haffTree[n+i].weight = haffTree[x1].weight+haffTree[x2].weight;
		haffTree[n+i].leftChild = x1;
		haffTree[n+i].rightChild = x2;
	}
	cout<<"构造完成。"<<endl;
}
void HaffmanCode(HaffNode haffTree[], int n, Code haffCode[])
//由n个结点的哈夫曼树haffTree构造哈夫曼编码haffCode
{
	Code *cd = new Code;
	int child, parent;
	int j,i;	
	//求n个叶结点的哈夫曼编码
	for(i = 0; i < n; i++)		
	{
		cd->start = n-1;		//不等长编码的最后一位为n-1
		cd->x=haffTree[i].x;
		cd->weight = haffTree[i].weight;	//取得编码对应权值的字符
		child = i;
		parent = haffTree[child].parent;		//由叶结点向上直到根结点
		while(parent != 0)
		{
			if(haffTree[parent].leftChild == child)
				cd->bit[cd->start] = '0';				//左孩子结点编码0
			else							
				cd->bit[cd->start] = '1';				//右孩子结点编码1
			cd->start--;
			child = parent;
			parent = haffTree[child].parent;
		}
		
		//保存叶结点的编码和不等长编码的起始位
		for(j = cd->start+1; j < n; j++) 
			haffCode[i].bit[j]=cd->bit[j];
		haffCode[i].start  = cd->start;
		haffCode[i].weight = cd->weight;//记住编码对应权值的字符
		haffCode[i].x=cd->x;
	}
	for(i = 0; i < n; i++)
	{
		cout <<"字符为:"<<haffCode[i].x<<" "<< "Weight = " << haffCode[i].weight << "   Code = ";
		for(j = haffCode[i].start+1; j < n; j++)
			cout << haffCode[i].bit[j];
		cout << endl;
	}
	cout<<"编码成功。"<<endl;
}
HaffNode *creat(int &n)
{
	HaffNode *haffTree = new HaffNode[2*n+1];
	int i=0;
	cout<<"请输入"<<n<<"个字符:";
	for(i=0;i<n;i++)
		cin>>haffTree[i].x;
	cout<<"请输入对应的权值:";
	
	//哈夫曼树haffTree初始化。n个叶结点的哈夫曼树共有2n-1个结点
	for(i=0; i < 2 * n - 1 ; i++)
	{
		if(i<n)
			cin>>haffTree[i].weight;
		else
			haffTree[i].weight = 0;
		haffTree[i].parent = 0;
		haffTree[i].flag   = 0;
		haffTree[i].leftChild = -1;
		haffTree[i].rightChild = -1;
	}
	return haffTree;
}
void deHaffmanCode(int n,Code haffCode[])
{
	char f[10];
	cout<<"请输入码字:";
	cin>>f;
	int i,j,m,b=0;
	for(i=0;i<n;i++)
	{
		j=haffCode[i].start+1;
		for(m=0;j<n;m++,j++)
			if(haffCode[i].bit[j]!=f[m])
				break;
			if(j>=n&&f[m]=='\0')			
			{
				b++;
				cout <<"字符为:"<<haffCode[i].x<<" "<< "Weight = " << haffCode[i].weight<<endl;
			}			
	}
	if(b==0)
		cout<<"不存在这样的码字。请重新输入!"<<endl;
}
int main()
{
	int i=0,n;
	HaffNode *myHaffTree;
	Code *myHaffCode;
	while(i!=5)
	{
		cout<<"--------1.输入数据。"<<endl;
		cout<<"--------2.构造赫夫曼树。"<<endl;
		cout<<"--------3.构造赫夫曼编码。"<<endl;
		cout<<"--------4.译码。"<<endl;
		cout<<"--------5.退出。"<<endl;
		cout<<"请选择:"<<endl;
		cin>>i;
		switch(i)
		{
		case 1:
			cout<<"请输入数据的个数:";
			cin>>n;
			myHaffTree = new HaffNode[2*n+1];
			myHaffTree=creat(n);
			myHaffCode = new Code[n];
			break;
		case 2:
			Haffman(n, myHaffTree);
			break;
		case 3:
			HaffmanCode(myHaffTree,n,myHaffCode);
			break;
		case 4:
			deHaffmanCode(n,myHaffCode);
			break;
		case 5:
			break;
		default:
			break;
		}		
	}	
	return 0;	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -