?? 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 + -