哈夫曼树的select函数和哈夫曼树的创建

qq_33428266 2016-05-31 01:45:52
#include <iostream>
#include<stdio.h>
#include<string.h>
typedef char **HuffmanCode;
typedef struct
{
int weight;
int parent;
int lchild;
int rchild;
}HTNode,*HuffmanTree;
void select(HuffmanTree &HT,int m,int &S1,int &S2)
{
int j;
S1=0;
S2=0;
for(j=1;j<=m;j++)
{
while(HT[j].parent==0)
{
if(HT[j].weight<HT[S1].weight)
S1=j;
}
}
for(j=1;j<=m;j++)
{
while(HT[j].parent==0&&j!=S1)
{
if(HT[j].weight<HT[S2].weight)
S2=j;
}
}

}
void CreateHuffmanTree(HuffmanTree &HT,int n,int &S1,int &S2)
{
int m;
int i;
if(n<=1)
{printf("叶子结点不足2个\n");
return;}
m=2*n-1;
HT=new HTNode[m+1];
for(i=1;i<m;i++)
{
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(i=1;i<=n;i++)
{
printf("请输入第%d个叶子结点的权值(频率*100)\n",i);
scanf("%d",&HT[i].weight);
}
/*初始化结束*/
for(i=n+1;i<=m;i++)
{
select(HT,i-1,S1,S2);
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;
}
printf("哈夫曼树创建完成\n");

}
void CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
{
int i,c,f;
int start;
char cd[n];
HC=new char*[n+1];
cd[n-1]='\0';
for(i=1;i<n;i++)
{
start=n-1;
c=i;f=HT[i].parent;
while(f!=0)
{
--start;
if(HT[f].lchild==c)
cd[start]='0';
else
cd[start]='1';
c=f;f=HT[f].parent;
}
HC[i]=new char[n-start];
strcpy(HC[i],&cd[start]);
}
delete cd;
}
int main()
{
int S1,S2;
int n;
HuffmanTree HT;
HuffmanCode HC;
printf("请输入叶子结点个数\n");
scanf("%d",&n);
CreateHuffmanTree(HT,n,S1,S2);
CreateHuffmanCode(HT,HC,n);

}
...全文
2796 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
坐端端同学 2019-11-10
  • 打赏
  • 举报
回复
void Select(HuffmanTree HT, int rear, int &s1, int &s2) {
//从HT[k]中选择双亲为0且权值最小的两个结点,并且返回他们在HT中的序号s1,s2
//其中1<=k<=rear
//要在双亲为0的结点中寻找,所以需要两遍循环寻找初始的min1和min2,作为比较的开始
int min1;
for (int i = 1; i <= rear; i++) {
if (!HT[i].parent) {//HT[i].parent==0
min1 = i;
break;
}

}
int min2;
for (int i = 1; i <= rear; i++) {
if ((!HT[i].parent)&&(i!=min1)) {//min1不能等于min2
min2 = i;
break;
}
}
//寻找第一个最小值
for (int i = 1; i <= rear; i++) {
if (HT[i].weight < HT[min1].weight && !HT[i].parent && (min2 != i)) {
min1 = i;
}
}

//寻找第二个最小值
for (int i = 1; i <= rear; i++) {
if (HT[i].weight < HT[min2].weight && !HT[i].parent&&(min1!=i)) {
min2 = i;
}
}

//打印寻找的最小值
s1 = min1;
s2 = min2;
cout <<"min1="<< min1 <<" min2=" << min2 << endl;
}
千面如是。 2019-06-15
  • 打赏
  • 举报
回复
那怎么修改呢?
休止符x 2017-12-04
  • 打赏
  • 举报
回复
确实卡在Select函数里了
小灸舞 2016-05-31
  • 打赏
  • 举报
回复
卡在select函数里的while(HT[j].parent==0)
即没有修改j也没有修改parent所以跳不出while
qq_33428266 2016-05-31
  • 打赏
  • 举报
回复
55-65行的for循环出不来。。。。死里面了、、、
#include #include #include #include using namespace std; # define MaxN 100//初始设定的最大结点数 # define MaxC 1000//最大编码长度 # define ImpossibleWeight 10000//结点不可能达到的权值 # define n 26//字符集的个数 //-----------哈夫曼树的结点结构类型定义----------- typedef struct //定义哈夫曼树各结点 { int weight;//权值 int parent;//双亲结点下标 int lchild;//左孩子结点下标 int rchild;//右孩子结点下标 }HTNode,*HuffmanTree;//动态分配数组存储哈夫曼树 typedef char**HuffmanCode;//动态分配数组存储哈夫曼编码表 //-------全局变量-------- HuffmanTree HT; HuffmanCode HC; int *w;//权值数组 //const int n=26;//字符集的个数 char *info;//字符值数组 int flag=0;//初始化标记 //********************************************************************** //初始化函数 //函数功能: 从终端读入字符集大小n , 以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中 //函数参数: //向量HT的前n个分量表示叶子结点,最后一个分量表示根结点,各字符的编码长度不等,所以按实际长度动态分配空间 void Select(HuffmanTree t,int i,int &s1,int &s2) { //s1为最小的两个值中序号最小的那个 int j; int k=ImpossibleWeight;//k的初值为不可能达到的最大权值 for(j=1;j<=i;j++) { if(t[j].weight哈夫曼树HT,并求出n个字符的哈弗曼编码HC { int i,m,c,s1,s2,start,f; HuffmanTree p; char* cd; if(num<=1) return; m=2*num-1;//m为结点数,一棵有n个叶子结点的哈夫曼树共有2n-1个结点,可以存储在一个大小为2n-1的一维数组中 HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未用 //--------初始化哈弗曼树------- for(p=HT+1,i=1;iweight=*w; p->parent=0; p->lchild=0; p->rchild=0; } for(i=num+1;iweight=0; p->parent=0; p->lchild=0; p->rchild=0; } //--------建哈夫曼树------------- for(i=num+1;i<=m;i++) { Select(HT,i-1,s1,s2);//在HT[1...i-1]选择parent为0且weight最小的两个结点,其序号分别为s1和s2 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; } //-------从叶子到根逆向求每个字符的哈弗曼编码-------- HC=(HuffmanCode)malloc((num+1)*sizeof(char *));//指针数组:分配n个字符编码的头指针向量 cd=(char*)malloc(n*sizeof(char*));//分配求编码的工作空间 cd[n-1]='\0';//编码结束符 for(i=1;i<=n;i++)//逐个字符求哈弗曼编码 { start=n-1;//编码结束符位置 for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)//从叶子到跟逆向求哈弗曼编码 if(HT[f].lchild==c) cd[--start]='0';//判断是左孩子还是右孩子(左为0右为1) else cd[--start]='1'; HC[i]=(char*)malloc((num-start)*sizeof(char*));//按所需长度分配空间 int j,h; strcpy(HC[i],&cd[start]); } free(cd); } //****************初始化函数****************** void Initialization() { flag=1;//标记为已初始化 int i; w=(int*)malloc(n*sizeof(int));//为26个字符权值分配空间 info=(char*)malloc(n*sizeof(char));//为26个字符分配空间 ifstream infile("ABC.txt",ios::in); if(!infile) { cerr<<"打开失败"<info[i]; infile>>w[i]; } infile.close(); cout<<"读入字符成功!"<哈夫曼树写入文件------------ cout<<"下面将哈夫曼树写入文件"<函数************************* void Input() { char string[100]; ofstream outfile("ToBeTran.txt",ios::out); if(!outfile) { cerr<<"打开失败"<string; for(int i=0;string[i]!='\0';i++) { if(string[i]=='\0') break; outfile<函数**************** void Encoding() { int i,j; char*string; string=(char*)malloc(MaxN*sizeof(char)); cout<<"下面对根目录下的ToBeTran.txt文件中的字符进行编码"<string[i]; } for(i=0;i<100;i++) if(string[i]!='#') cout<函数**************** void Decoding() { int j=0,i; char *code; code=(char*)malloc(MaxC*sizeof(char)); char*string; string=(char*)malloc(MaxN*sizeof(char)); cout<<"下面对根目录下的CodeFile.txt文件中的代码进行译码"<code[i]; if(code[i]!='#') { cout<函数**************** void Code_printing() { int i; char *code; code=(char*)malloc(MaxC*sizeof(char)); cout<<"下面打印根目录下文件CodeFile.txt中的编码"<code[i]; if(code[i]!='#') cout<哈夫曼树函数**************** int numb=0; void coprint(HuffmanTree start,HuffmanTree HT) //start=ht+26这是一个递归算法 { if(start!=HT) { ofstream outfile("TreePrint.txt",ios::out); if(!outfile) { cerr<<"打开失败"lchild,HT); numb--; outfile.close(); } } void Tree_printing(HuffmanTree HT,int num) { HuffmanTree p; p=HT+2*num-1; //p=HT+26 cout<<"下面打印赫夫曼树"<函数************************** int main() { char choice; do{ cout<<"************哈弗曼编/译码器系统***************"<哈夫曼树进行编码"<哈夫曼树进行译码"<哈夫曼树"<哈夫曼树,输入I"<choice; switch(choice) { case 'I':Initialization();break; case 'W':Input();break; case 'E':Encoding();break; case 'D':Decoding();break; case 'P':Code_printing();break; case 'T':Tree_printing(HT,n);break; case 'Q':;break; default:cout<<"输入的命令出错,请重新输入!"<
问题描述: 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码,请设计这样的一个简单编/译码系统。 基本要求: (1)接收原始数据: 从终端读入字符集大小n,n个字符和n个权值,建立哈夫曼树,存于文件hfmtree.dat中。 (2)编码: 利用已建好的哈夫曼树(如不在内存,则从文件hfmtree.dat中读入)对文件中的正文进行编码,然后将结果存入文件codefile.dat中。 (3)译码: 利用已建好的哈夫曼树将文件codefile.dat中的代码进行译码,结果存入文件textfile.dat 中。 (4)打印编码规则:即字符与编码的一一对应关系。 (5)打印哈夫曼树:将已在内存中的哈夫曼树以直观的方式显示在终端上。 实现提示 构造哈夫曼树时使用静态链表作为哈夫曼树的存储。求哈夫曼编码,实质上就是在已建立的哈夫曼树中,从叶子结点开始,沿结点的双亲链域回退到根结点,每回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值。由于一个字符的哈夫曼编码是从根结点到相应叶子结点所经过的路径上各分支所组成的0,1序列,因此先得到的分支代码为所求编码的低位码,后得到的分支代码为所求编码的高位码。 #include #include #include #include #define NULL 0 #define MAX_NUM 10000 #define MAX 60 int j=0; typedef int Status; typedef char **HuffmanCode; typedef struct{ unsigned int weight;//字符对应的权值 unsigned int parent,lchild,rchild; }HTNode,*HuffmanTree;//此处定义了哈夫曼树节点的数据类型。提供给Huffman使用 typedef struct{ HuffmanTree HT; char *c;//存放将要建立哈夫曼树的字符 int longth;//字符的大小,即开始第一步输入的一个整数 HuffmanCode HC;//存放对应的哈夫编码即对应的01代码 }Huffman; void Select(HuffmanTree HT,int end,int *s1,int *s2) //把输入的字符按权值从小到大排序,挑出最小权值供HuffmanCoding()调用 //并且根节点的权值等于他的左右孩子的权值和 //min2是在剩下的字符中挑出的最小的劝值的字符 { int i; int min1=MAX_NUM;//min1是根节点的权值 int min2;//min2是在剩下的字符中挑出的最小的权值的字符 for (i=1;i<=end;i++) { if (HT[i].parent==0&&HT[i].weightSelect(Hfm.HT,i-1,&s1,&s2); Hfm.HT[s1].parent=i; Hfm.HT[s2].parent=i; Hfm.HT[i].lchild=s1; Hfm.HT[i].rchild=s2; Hfm.HT[i].weight=Hfm.HT[s1].weight+Hfm.HT[s2].weight; //构造哈夫曼树时候,根节点的权值等于他的左右孩子权值和 //test printf("

64,654

社区成员

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

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