哈夫曼树的实现

#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;

const int MAXVALUE = 99999; //初始设定的权值最大值
const int MAXBIT = 10; //初始设定的最大编码位数
const int MAXN = 1000; //初始设定的最大结点个数

struct HaffNode //哈夫曼树的结点结构
{
int weight; //权值
int flag; //标记
int parent; //双亲结点下标
int leftChild; //左孩子下标
int rightChild; //右孩子下标
};

struct Code //存放哈夫曼编码的数据元素结构
{
int bit[MAXBIT]; //数组
int start; //编码的起始下标
int weight; //字符的权值
};

void Haffman(int weight[], int n, HaffNode haffTree[]);//建树
void HaffmanCode(HaffNode haffTree[], int n, Code haffCode[]);//生成哈夫曼编码
void Coding(char str[], char s[], int n, Code code[]);
void DeCoding(int n, char s[], HaffNode hafftree[]);
void PreOrder(HaffNode haffTree[], int n);
void InOrder(HaffNode haffTree[], int n);

int main()
{
int i, weight[MAXN], len;
char strChar[MAXN], c;
bool flag = true;
HaffNode *hafftree;
Code *haffcode;

while(flag)
{
cin >> c;
switch(c)
{
case 'B':
{
cin>>strChar;
len = strlen(strChar);
for(i=0; i<len; i++)
cin >> weight[i];
hafftree = new HaffNode[2*len-1];
Haffman(weight, len, hafftree);
}
break;

case 'E':
{
haffcode = new Code[len];
HaffmanCode(hafftree, len, haffcode);
}
break;

case 'T':
{
PreOrder(hafftree, 2*len-2);
cout << endl;
InOrder(hafftree, 2*len-2);
cout << endl;
}
break;

case 'C':
{
char strInput[MAXN];
cin >> strInput;
Coding(strInput, strChar, len, haffcode);
}
break;

case 'D':
{
DeCoding(len, strChar, hafftree);
}
break;

case 'P':
{
}
break;

case 'X':
{
flag = false;
}
break;

case 'S':
{
}
break;

default:
break;
}
}
return 0;
}

{
cout<<"********************************************************************"<<endl;
cout<<"* B—建树:   读入字符集和各字符频度，建立哈夫曼树。*****************"<<endl;
cout<<"********************************************************************"<<endl;
cout<<"* T—遍历:   先序和中序遍历二叉树。                *****************"<<endl;
cout<<"********************************************************************"<<endl;
cout<<"* E—生成编码: 根据已建成的哈夫曼树，产生各字符的哈夫曼编码。*******"<<endl;
cout<<"********************************************************************"<<endl;
cout<<"* C—编码:   输入由字符集中字符串组成的任意字符串，利用已生成的 ****"<<endl;
cout<<"*            哈夫曼编码,显示编码结果，并将输入的字符串及其编码  ****"<<endl;
cout<<"*            结果分别保存在磁盘文件textfile.txt和codefile.txt中。***"<<endl;
cout<<"********************************************************************"<<endl;
cout<<"* D—译码:   读入codefile.txt,利用建议建成的哈夫曼树进行译码，******"<<endl;
cout<<"*            并将译码结果放入磁盘文件result.txt。             ******"<<endl;
cout<<"********************************************************************"<<endl;
cout<<"* P—打印:   屏幕显示文件textfile.txt、codefile.txt和result.txt。***"<<endl;
cout<<"********************************************************************"<<endl;
cout<<"* X—退出。                           ******************************"<<endl;
cout<<"********************************************************************"<<endl;
}

void Haffman(int weight[], int n, HaffNode haffTree[])
//建立叶结点个数为n权值为weight的哈夫曼树haffTree
{
int j, m1, m2, x1, x2;
//哈夫曼树haffTree初始化。n个叶结点的哈夫曼树共有2n-1个结点
for(int i = 0; i < 2 * n - 1 ; i++)
{
if(i < n)
haffTree[i].weight = weight[i];
else
haffTree[i].weight = 0;
haffTree[i].parent = 0;
haffTree[i].flag = 0;
haffTree[i].leftChild = -1;
haffTree[i].rightChild = -1;
}
//构造哈夫曼树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;
}
}

void HaffmanCode(HaffNode haffTree[], int n, Code haffCode[])
//由n个结点的哈夫曼树haffTree构造哈夫曼编码haffCode
{
Code *cd = new Code;
int child, parent;
//求n个叶结点的哈夫曼编码
for(int i = 0; i < n; i++)
{
cd->start = n-1; //不等长编码的最后一位为n-1
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(int j = cd->start+1; j < n; j++)
haffCode[i].bit[j] = cd->bit[j];
haffCode[i].start = cd->start;
haffCode[i].weight = cd->weight; //保存编码对应的权值
}
}

void Coding(char str[], char s[], int n, Code code[])
{
ofstream outf("textfile.txt");
int len = strlen(str);

if(!outf)
{
cout << "cannot open the file\n";
return ;
}

outf << str;
outf << endl;
outf.close();

ofstream outfc("codefile.txt");
if(!outfc)
{
cout << "cannot open the file\n";
return ;
}
for(int i=0; i<len; i++)
{
for(int j=0; j<n; j++)
{
if(str[i] == s[j])
break;
}
for(int k=code[j].start+1; k<n; k++)
outfc << code[j].bit[k];
}
outfc << endl;
outfc.close();
}

void DeCoding(int n, char s[], HaffNode hafftree[])
{
ifstream inf("codefile.txt");
char str[MAXN];
inf >> str;

ofstream outf("result.txt");
int len = strlen(str);

int j = 2 * n - 2;
for(int i=0; i<len; i++)
{
if('0' == str[i])
{
if(0 <= hafftree[j].leftChild && hafftree[j].leftChild < n)
{
outf << s[hafftree[j].leftChild];
j = 2 * n - 2;
}
else
j = hafftree[j].leftChild;
}
else
{
if(0 <= hafftree[j].rightChild && hafftree[j].rightChild < n)
{
outf << s[hafftree[j].rightChild];
j = 2 * n - 2;
}
else
j = hafftree[j].rightChild;
}
}

inf.close();
outf.close();
}

{
ifstream inf(s);
char str[MAXN];
inf >> str;
cout << s << ":" << str << endl;
inf.close();
}

void PreOrder(HaffNode haffTree[], int n)
{
if(n > -1)
{
cout << haffTree[n].weight << " ";
PreOrder(haffTree, haffTree[n].leftChild);
PreOrder(haffTree, haffTree[n].rightChild);
}
}

void InOrder(HaffNode haffTree[], int n)
{
if(n > -1)
{
InOrder(haffTree, haffTree[n].leftChild);
cout << haffTree[n].weight << " ";
InOrder(haffTree, haffTree[n].rightChild);
}
}

• 本文已收录于以下专栏：

哈夫曼树的c++实现

huffman 树称为最优二叉树，用其来对字符编码是一种比较好的选择，huffman树的实现也比较简单，构造huffman树的思想就是每次从序列中取出权值最小的两个，然后构造出一个树，然再去构造，一直...
• hujian_
• 2016年05月24日 11:21
• 1412

哈夫曼树-贪心算法的应用实例

/* *哈夫曼编码-链式结构 * *功能实现： * 源文件字符权值确认操作 * 哈夫曼树的建立操作 * 字符字典的建立操作 * 源文件转码操作操作 * 二进制文件译码操作 * 文件输出操作...
• a915650754
• 2014年12月07日 23:11
• 1401

哈夫曼树及一种java实现

• Allenalex
• 2016年03月23日 20:54
• 969

数据结构(15)--哈夫曼树以及哈夫曼编码的实现

1.哈夫曼树     假设有n个权值{w1, w2, ..., wn}，试构造一棵含有n个叶子结点的二叉树，每个叶子节点带权威wi，则其中带权路径长度WPL最小的二叉树叫做最优二叉树或者哈夫曼树。  ...
• u010366748
• 2016年03月01日 17:28
• 6254

树结构(四) - 哈夫曼树的原理与实现

• leicool_518
• 2015年01月13日 13:24
• 2006

哈夫曼树的代码实现

• cqnuztq
• 2013年05月13日 10:20
• 20280

Python使用优先队列，树结构实现哈夫曼算法（哈夫曼树）

• cube_ice
• 2017年12月13日 20:04
• 193

哈夫曼树的实现及其实例分析

• ldx19980108
• 2017年11月20日 22:56
• 647

哈夫曼树编码C语言实现

• qq_29187355
• 2017年05月06日 01:46
• 861

哈夫曼树数据机构的建立及哈夫曼编码与解码的C++实现

• Alex123980
• 2016年06月08日 21:46
• 1174

举报原因： 您举报文章：哈夫曼树的实现 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)