做哈夫曼编译器译码器课程设计要知道哪些内容

IT_FrankShaw 2009-12-16 08:47:27
比如要不要位运算操作,另外难度怎么样?
...全文
112 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
ptf343656 2009-12-17
  • 打赏
  • 举报
回复
自己无聊写的
#include<iostream>
using namespace std;
typedef struct
{
int weight;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
void HuffmanCoding(HuffmanTree&,int*,int);
void select(HuffmanTree,int,int&,int&);

//冒泡法的弊端,因为slHT和HT引用的是同一块内存,所以改变slHT[i]的值HT[i]的值也改变。不合适。故使用选择排序法找出最小。(以下为一部分冒泡)
//void select(HuffmanTree slHT,int n,int& s1,int& s2)
//{
// int zjl; // 声明一中间量
// for(int i=0;i<n-1;i++)//冒泡法找出最小值,需要循环两次(试着找出循环一次的算法)
// {
// if(slHT[i].weight!=0&&slHT[i].parent==0)
// {
// int j=i+1;
// if(slHT[i].weight<slHT[j].weight)
// {
// zjl=slHT[j].weight;
// slHT[j].weight=slHT[i].weight;
// slHT[i].weight=zjl;
// s1=i;
// }
// else
// {
// s1=j;
// }
// }
// }
//}

//用选择排序找出最小值
void select(HuffmanTree slHT,int n,int& s1,int& s2)
{
int min,k;//定义两个初始变量,分别存放其他要与之比较的值

//因为每次循环都使节点的parent值改变,所以必须动态生成初始变量的值。
for(k=0;k<n;k++)
{
if(slHT[k].parent==0)
{
min=slHT[k].weight;
s1=k;
break;//找到第一个符合条件的值就跳出循环
}
}
//与min比较,找出最小值
for(int i=k+1;i<n;i++) //因为前K个已经不满足slHT[i]==0,而且也不需要与本身比较,故可以从K+1开始
{
if(slHT[i].parent==0&&slHT[i].weight<min)
{
min=slHT[i].weight;
s1=i;
}
}
//动态找出次小值的初始值,使其他与之比较
for(k=0;k<n;k++)
{
if(slHT[k].parent==0&&k!=s1)
{
min=slHT[k].weight;
s2=k;
break; //break的作用
}
}
//找出次小值
for(int i=k+1;i<n;i++)
{
if(slHT[i].parent==0&&slHT[i].weight<min&&i!=s1)//因为s1已经放了最小值,所以不能与s1下标的值比较
{
min=slHT[i].weight;
s2=i;
}
}
}
void HuffmanCoding(HuffmanTree& HT,int* w,int n)
{
//初始化HT各个节点。
int i;
HuffmanTree p;
if(n<=1)return;
int m=2*n-1; //根据二叉树性质
HT=new HTNode[m+1];
for( i=1,p=HT;i<=n;i++,p++,w++)//同样的原因用p代替HT(循环完后会使指针指向数组末尾)
{
p->weight=*w;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(;i<=m;i++,p++)
{
p->lchild=0;
p->parent=0;
p->rchild=0;
p->weight=0;
}
//建立赫夫曼树
for(i=n;i<m;i++)//因为已存在n个叶子节点,故只需要根据叶子节点和赫夫曼树性质建立其他m-(n-1)个节点。
{
int s1,s2;
select(HT,i,s1,s2);//每次从有权的节点中找出两个权值最小的节点放入s1,s2中,i-1为需要比较的节点个数。
HT[s1].parent=i;HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
for(int i=0;i<m;i++)
{
cout<<HT[i].weight<<" ";
cout<<HT[i].parent<<" ";
cout<<HT[i].lchild<<" ";
cout<<HT[i].rchild;
cout<<endl;
}
////从叶子到根逆向求出每个字符的赫夫曼编码

char* cd=new char[n]; //定义临时装每个字符的编码0,1
char** cha=new char*[n];//每个字符的编码放进cha中
cd[n-1]='\0'; //定义编码的最后一个元素为/0
int c,start;
HuffmanTree t;
for(int i=0,k=i;i<n;i++,k++) //遍历每个叶子节点,也就是把前n个节点编码,定义k,与i同步,因为在for语句中会改变i的值,
{ //故需要定义k,保持i没循环一次增加1。
start=n-1;
t=HT;
cha[i]=new char[n]; //每次循环创建char[]来存放临时cd中的值。
while(t[i].parent!=0) //编码,从叶子直到根。
{
c=i;
i=t[i].parent;
if(t[i].lchild==c)
cd[--start]='0';
else if(t[i].rchild==c)
cd[--start]='1';
}
for(int j=0;j<n;j++,start++) //将临时cd[]中的数据(编码)放入cha数组中
{
cha[k][j]=cd[start];
}
i=k;
}
delete cd;
//打印出编码值
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
cout<<cha[i][j];
cout<<endl;
}

////从根到叶子编码 由于下标是从0开始的,故当HT[i]的下一个节点为0节点时出现错误。
//for(int i=0;i<m;i++)
// HT[i].weight=0;
//int cdlen=0,q=m-1;//p为根节点编号
//while(q) //当p为0时退出循环,由于HT是从小标为0开始,所以当p的lchild或rchild为HT[0]时,会发生错误。
//{
// if(HT[q].weight==0)
// {
// HT[q].weight=1;
// if(HT[q].lchild!=0)
// {
// q=HT[q].lchild;
// cd[cdlen++]='0';
// }
// else if(HT[q].rchild==0)
// {
// cha[q]=new char[n];
// cd[cdlen]='\0';
// for(int j=0;j<n;j++)
// {
// cha[q][j]=cd[j];
// cout<<cha[q][j];
// }
// cout<<endl;
// }
// }
// else if(HT[q].weight==1)
// {
// HT[q].weight=2;
// if(HT[q].rchild!=0)
// {
// q=HT[q].rchild;
// cd[cdlen++]='1';
// }
// }
// else
// {
// HT[q].weight=0;q=HT[q].parent; //到根节点时,它的父节点为0;则退出循环。
// --cdlen;
// }
//}
// for(int i=2;i<n;i++)
//{
// for(int j=0;j<n;j++)
// cout<<cha[i][j];
// cout<<endl;
//}
}
void main()
{
HuffmanTree HT;
int* w=new int[8];
int*c;
c=w; //如果直接用w,循环完后会使指针指向数组末尾,故应使用变量c;也可以使用w[i]形式赋值。
for(int i=0;i<8;i++,c++)
{
cin>>*c;
}
HuffmanCoding(HT,w,8);
}
liang0356 2009-12-16
  • 打赏
  • 举报
回复
支持楼上。位运算不是硬性条件,用不用取决于自己,二叉树是必须的。
ypb362148418 2009-12-16
  • 打赏
  • 举报
回复
指导Huffman是如何编码的,还有就是知道二叉树就行了
selooloo 2009-12-16
  • 打赏
  • 举报
回复
要了解二叉树
  • 打赏
  • 举报
回复
多看书,慢慢就理解了
qqwx_1986 2009-12-16
  • 打赏
  • 举报
回复
知道原理很简单的
位运算就几个,看一下就明白了
sduxiaoxiang 2009-12-16
  • 打赏
  • 举报
回复
知道hoffman编码怎么回事就可以了

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧