数据结构
时间:2011-11-28
来源:互联网
#include <iostream>
using namespace std;
//Huffman树的存储结构
#define n 5 //叶子数目
#define m 2*n-1 //树中结点总数
typedef struct //结点类型
{ float weight; //权值,不妨设权值均大于零
int lchild,rchild,parent; //左右孩子及双亲指针
}HTNode;
typedef HTNode HuffmanTree[m]; //HuffmanTree是向量类型
typedef struct
{ char ch; //存储字符
char bits[n+1]; //存放编码位串
}CodeNode;
typedef CodeNode HuffmanCode[n];
void CreateHuffmanTree(HuffmanTree T);//构造Huffman树,T[m-1]为其根结点
void InitHuffmanTree(HuffmanTree T); //初始化Huffman树
void InputWeight(HuffmanTree T); //输入权值
void SelectMin(HuffmanTree T,int i,int *p1,int *p2);//在T中选择两个权最小的根结点
void CharSetHuffmanEncoding(HuffmanTree T,HuffmanCode H);//根据Huffman树T求Huffman编码表H
void main()
{
HuffmanTree T;
HuffmanCode H;
CreateHuffmanTree(T);
CharSetHuffmanEncoding(T,H);
}
void CreateHuffmanTree(HuffmanTree T)
{ //构造Huffman树,T[m-1]为其根结点
int i,p1,p2;
InitHuffmanTree(T); //将T初始化
InputWeight(T); //输入叶子权值至T[0..n-1]的weight域
for(i=n;i<m;i++) //共进行n-1次合并,新结点依次存于T[i]中
{ SelectMin(T,i-1,&p1,&p2);
//在T[0..i-1]中选择两个权最小的根结点,其序号分别为p1和p2
T[p1].parent=T[p2].parent=i;
T[i].lchild=p1; //最小权的根结点是新结点的左孩子
T[i].rchild=p2; //次小权的根结点是新结点的右孩子
T[i].weight=T[p1].weight+T[p2].weight;
}
}
void InitHuffmanTree(HuffmanTree T)
{ //初始化Huffman树
int i;
for (i=0;i<m;i++)
{
T[i].weight=0;
T[i].lchild=T[i].rchild=T[i].parent=NULL;
}
}
void InputWeight(HuffmanTree T)
{ //输入权值
int i;
for (i=0;i<n;i++)
{
cout<<"请输入第"<<i+1<<"个权值:";
cin>>T[i].weight;
}
}
void SelectMin(HuffmanTree T,int i,int *p1,int *p2)
{ //在T中选择两个权最小的根结点
int j;
float min1,min2;
min1=min2=-1;
for(j=0;j<=i;j++)
if(T[j].parent==NULL)
{
if(T[j].weight<min1||min1==-1)
{
if(min1!=-1)
{
min2=min1;
*p2=*p1;
}
min1=T[j].weight;
*p1=j;
}
else
if(T[j].weight<min2||min2==-1)
{
min2=T[j].weight;
*p2=j;
}
}
}
void CharSetHuffmanEncoding(HuffmanTree T,HuffmanCode H)
{ //根据Huffman树T求Huffman编码表H
int c,p,i; //c和p分别指示T中孩子和双亲的位置
char cd[n+1]; //临时存放编码
char str[n+1]; //存放输入字符串
int start; //指示编码在cd中的起始位置
cd[n]='\0'; //编码结束符
cout<<"请输入字符串:";
cin>>str;
for(i=0;i<n;i++) //依次求叶子T[i]的编码
{
H[i].ch=str[i]; //读入叶子T[i]对应的字符
start=n; //编码起始位置的初值
c=i; //从叶子T[i]开始上溯
while((p=T[c].parent)!=NULL)//直至上溯到T[c]是树根为止
{ //若T[c]是T[p]的左孩子,则生成代码0;否则生成代码1
cd[--start]=(T[p].lchild==c)?'0':'1';
c=p; //继续上溯
}
strcpy(H[i].bits,&cd[start]); //复制编码位串
}
for(i=0;i<n;i++)
cout<<"第"<<i+1<<"个字符"<<H[i].ch<<"的编码为"<<H[i].bits<<endl;
}
请问这段代码中怎么实现任意个字符的哈弗曼编码??
using namespace std;
//Huffman树的存储结构
#define n 5 //叶子数目
#define m 2*n-1 //树中结点总数
typedef struct //结点类型
{ float weight; //权值,不妨设权值均大于零
int lchild,rchild,parent; //左右孩子及双亲指针
}HTNode;
typedef HTNode HuffmanTree[m]; //HuffmanTree是向量类型
typedef struct
{ char ch; //存储字符
char bits[n+1]; //存放编码位串
}CodeNode;
typedef CodeNode HuffmanCode[n];
void CreateHuffmanTree(HuffmanTree T);//构造Huffman树,T[m-1]为其根结点
void InitHuffmanTree(HuffmanTree T); //初始化Huffman树
void InputWeight(HuffmanTree T); //输入权值
void SelectMin(HuffmanTree T,int i,int *p1,int *p2);//在T中选择两个权最小的根结点
void CharSetHuffmanEncoding(HuffmanTree T,HuffmanCode H);//根据Huffman树T求Huffman编码表H
void main()
{
HuffmanTree T;
HuffmanCode H;
CreateHuffmanTree(T);
CharSetHuffmanEncoding(T,H);
}
void CreateHuffmanTree(HuffmanTree T)
{ //构造Huffman树,T[m-1]为其根结点
int i,p1,p2;
InitHuffmanTree(T); //将T初始化
InputWeight(T); //输入叶子权值至T[0..n-1]的weight域
for(i=n;i<m;i++) //共进行n-1次合并,新结点依次存于T[i]中
{ SelectMin(T,i-1,&p1,&p2);
//在T[0..i-1]中选择两个权最小的根结点,其序号分别为p1和p2
T[p1].parent=T[p2].parent=i;
T[i].lchild=p1; //最小权的根结点是新结点的左孩子
T[i].rchild=p2; //次小权的根结点是新结点的右孩子
T[i].weight=T[p1].weight+T[p2].weight;
}
}
void InitHuffmanTree(HuffmanTree T)
{ //初始化Huffman树
int i;
for (i=0;i<m;i++)
{
T[i].weight=0;
T[i].lchild=T[i].rchild=T[i].parent=NULL;
}
}
void InputWeight(HuffmanTree T)
{ //输入权值
int i;
for (i=0;i<n;i++)
{
cout<<"请输入第"<<i+1<<"个权值:";
cin>>T[i].weight;
}
}
void SelectMin(HuffmanTree T,int i,int *p1,int *p2)
{ //在T中选择两个权最小的根结点
int j;
float min1,min2;
min1=min2=-1;
for(j=0;j<=i;j++)
if(T[j].parent==NULL)
{
if(T[j].weight<min1||min1==-1)
{
if(min1!=-1)
{
min2=min1;
*p2=*p1;
}
min1=T[j].weight;
*p1=j;
}
else
if(T[j].weight<min2||min2==-1)
{
min2=T[j].weight;
*p2=j;
}
}
}
void CharSetHuffmanEncoding(HuffmanTree T,HuffmanCode H)
{ //根据Huffman树T求Huffman编码表H
int c,p,i; //c和p分别指示T中孩子和双亲的位置
char cd[n+1]; //临时存放编码
char str[n+1]; //存放输入字符串
int start; //指示编码在cd中的起始位置
cd[n]='\0'; //编码结束符
cout<<"请输入字符串:";
cin>>str;
for(i=0;i<n;i++) //依次求叶子T[i]的编码
{
H[i].ch=str[i]; //读入叶子T[i]对应的字符
start=n; //编码起始位置的初值
c=i; //从叶子T[i]开始上溯
while((p=T[c].parent)!=NULL)//直至上溯到T[c]是树根为止
{ //若T[c]是T[p]的左孩子,则生成代码0;否则生成代码1
cd[--start]=(T[p].lchild==c)?'0':'1';
c=p; //继续上溯
}
strcpy(H[i].bits,&cd[start]); //复制编码位串
}
for(i=0;i<n;i++)
cout<<"第"<<i+1<<"个字符"<<H[i].ch<<"的编码为"<<H[i].bits<<endl;
}
请问这段代码中怎么实现任意个字符的哈弗曼编码??
作者: xianvchen900 发布时间: 2011-11-28
看看 哈弗曼编码 的算法吧?
作者: jixingzhong 发布时间: 2011-11-28
把 m 和 n 不要用宏来表示
数据用指针存
处理好输入 输出
内部算法不变
数据用指针存
处理好输入 输出
内部算法不变
作者: macrojj 发布时间: 2011-11-28
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28