📄 huffman.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 + -