为什么在调用Huffmancoding 这个函数后会导致head发生变化了?

问题描述

为什么在调用Huffmancoding 这个函数后会导致head发生变化了?

#include
#include
#include
int count=0;//用来计算叶子结点
int NUM=0;//用来计算短文字母总数
int min[2];
typedef struct Essays
{
char ch;
int num;
struct Essays *next;
}Essay;
typedef struct Huff_Trees
{
unsigned int weight;
unsigned int parent,lchild,rchild;
}Huff_Tree;
void write(char ch[])
{
int i=0;
FILE *fp;
if((fp=fopen("F:数据结构实验a.txt","w"))==NULL)
{
printf("can't open file a!n");
exit(0);
}
while(ch[i]!='')
{
fputc(ch[i],fp);
putchar(ch[i]);
i++;
}
putchar(10);
rewind(fp);
fclose(fp);
}
void count1(char cha[],Essay *head)
{
Essay *essay,*p,*end;
int i=0;
p=head;
end=head;
printf("正在计算短文的长度和各个字母出现的次数!n");
while(cha[i]!='')
{
for(p=head;p!=NULL;p=p->next)
{
if(p->ch==cha[i])
{
(p->num)++;
break;
}
}
if(p==NULL)
{
essay=(Essay *)malloc(1*sizeof( Essay));
essay->ch=cha[i];
essay->num=1;
essay->next=NULL;
end->next=essay;
end=end->next;
NUM++;
}
count++;
i++;
}
printf("计算结果如下:共有%d个字母,%d个不同的字母n",count,NUM);
printf("字母 出现次数n");
for(p=head->next;p!=NULL;p=p->next)
{
printf("%c %d",p->ch,p->num);
printf("n");
}
printf("计算结果显示完毕!n");
// free(essay);
}
void Select(Huff_Tree ht[],int n)
{
int i,j,tep=1;
for(i=1;i<=n;i++)
{
if(ht[i].parent==0)
{
if(tep==1)
min[0]=i;
else
min[1]=i;
tep++;
}
if(tep>2)
break;
}
if(min[0]>min[1])
{
tep=min[0];
min[0]=min[1];
min[1]=tep;
}
for(j=i+1;j<=n&&ht[j].parent==0;j++)
if(ht[j].weight<ht[min[1]].weight)
{
if(ht[j].weight<ht[min[0]].weight)
{
min[1]=min[0];
min[0]=j;
}
else
min[1]=j;
}
}

void HuffmanCoding(Essay head,char **HC,Huff_Tree HT[])
{
char *cd;
Essay *ess;
int m=2*NUM-1,term;
int i,s1,s2,start,c,f;
ess=head->next;
if(NUM<=1)
printf("该树只有一个结点!n");
cd=(char *)malloc(NUM*sizeof(char));

for(i=1;i<=NUM;i++,ess=ess->next)
{
HT[i].weight=ess->num;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(i=NUM+1;i<=m;i++)
{
HT[i].weight=0;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(i=NUM+1;i<=m;i++)//建立赫夫曼树
{
Select(HT,i-1);
s2=min[0];
s1=min[1];
if((HT[s1].lchild!=0||HT[s1].rchild!=0)&&(HT[s2].lchild==0||HT[s2].rchild==0))
{
term=s2;
s2=s1;
s1=term;
}
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("得出的赫夫曼树如下:nweight parent lchild rchildn");
for(i=1;i<=m;i++)
printf("%d %d %d %dn",HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
//求赫夫曼编码
printf("现在进行赫夫曼编码的求解:n");
cd[NUM-1]='';
for(i=1;i<=NUM;i++)
{
start=NUM-1;
for(c=i,f=HT[i].parent;HT[c].parent!=0;c=f,f=HT[f].parent)
{
if(HT[f].lchild==c)
cd[--start]='0';
else
cd[--start]='1';
}
HC[i]=(char *)malloc((NUM-start)*sizeof(char));
strcpy(HC[i],&cd[start]);
//printf("%sn",cd);
}
printf("赫夫曼编码如下:n");
for(i=1;i
puts(HC[i]);
//for(ess=head->next;ess!=NULL;ess=ess->next)
// printf("%c",ess->ch);
}
void coding(char ch1[],char **Hc,Essay *head)
{
int i,j,t=0;
char **code;
Essay *p;
FILE *fp;
code=(char *
)malloc((count)*sizeof(char ));
for(i=0;i
{
for(p=head->next,j=1;p!=NULL;p=p->next,j++)
if(ch1[i]==(p->ch))
{
code[t]=(char *)malloc((strlen(Hc[j]))*sizeof(char ));
strcpy(code[t],Hc[j]);
t++;
break;
}
}
if((fp=fopen("F:数据结构实验b.txt","w+"))==NULL)
{
printf("can't open file b!n");
exit(0);
}
for(i=0;i<count;i++)
fputs(code[i],fp);
rewind(fp);
fclose(fp);
/
FILE fp1,*fp2;
if((fp1=fopen("F:数据结构实验a.txt","r+"))==NULL)
{
printf("can't open file a!n");
exit(0);
}
if((fp2=fopen("F:数据结构实验b.txt","w+"))==NULL)
{
printf("can't open file b!n");
exit(0);
}
while(!feof(fp1))
fputc(fgetc(fp1),fp2);
//printf("b文件:n");
/*while(!feof(fp2))
putchar(fgetc(fp2));
putchar(10);
rewind(fp1);
rewind(fp2);
fclose(fp1);
fclose(fp2);
/
}
void decoding(char **Hc,Essay head)
{
FILE *fp;
char *word;//用来存储译码后的字母
char *temp;
int i,j,t=0;
Essay *p;
if((fp=fopen("F:数据结构实验c.txt","w+"))==NULL)
{
printf("can't open file c!n");
exit(0);
}
word=(char *)malloc(count*sizeof(char));
temp=(char *)malloc(NUM*sizeof(char));
while(!feof(fp))
{
i=0;
while(fgetc(fp)!='')
{
temp[i]=fgetc(fp);
i++;
}
temp[i]='';
for(j=1,p=head->next;j<=NUM;j++,p=p->next)
if(strcmp(Hc[j],temp)==0)
{
word[t]=p->ch;
t++;
}
}
for(i=0;i<count;i++)
fputc(word[i],fp);
rewind(fp);
fclose(fp);
}
void equal()
{
FILE *fp1,*fp2;
int flag=1;
if((fp1=fopen("F:数据结构实验a.txt","w+"))==NULL)
{
printf("can't open file a!n");
exit(0);
}
if((fp2=fopen("F:数据结构实验c.txt","w+"))==NULL)
{
printf("can't open file c!n");
exit(0);
}
while(!feof(fp1)&&!feof(fp2))
{
if(fgetc(fp1)!=fgetc(fp2))
{
printf("赫夫曼编码错误!!!n");
flag=0;
break;
}
}
if(flag==1)
printf("赫夫曼编码正确!!!n");
}
void main()
{
Essay *head,*p;
char ch2[]="dasda";
char **Hc;
Huff_Tree *HT;
HT=(Huff_Tree *)malloc((2*NUM)*sizeof(Huff_Tree));
head=(Essay *)malloc(sizeof(Essay));
Hc=(char *
)malloc((NUM+1)*sizeof(char *));
head->next=NULL;
head->ch='0';
head->num=0;
write(ch2);
count1(ch2,head);
printf("head里面的数据:n");
for(p=head->next;p!=NULL;p=p->next)
printf("%c %dn",p->ch,p->num);
HuffmanCoding(head,Hc,HT);
printf("head里面的数据:n");
for(p=head->next;p!=NULL;p=p->next)
printf("%c %dn",p->ch,p->num);
coding(ch2,Hc,head);
decoding(Hc,head);
equal();
}

解决方案

对于这段代码,我表示无能为力

解决方案二:

代码略长啊。。。。
不用单步也没关系
在HuffmanCoding函数里加几处下面两句打印head的语句,然后就能迅速定位出是哪个地方修改了head
for(p=head->next;p!=NULL;p=p->next)
printf("%c %dn",p->ch,p->num);

解决方案三:

我知道在head是在执行for(i=NUM+1;i<=m;i++) { HT[i].weight=0; HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; }后发生了变化,关键我是不明白为什么求解啊

时间: 2024-09-15 10:10:02

为什么在调用Huffmancoding 这个函数后会导致head发生变化了?的相关文章

C++程序调用已经被编译后的C函数

来自林锐的<高质量C++编程指南>答案: 如果C++程序要调用已经被编译后的C 函数,该怎么办? 假设某个C 函数的声明如下: void foo(int x, int y); 该函数被C 编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字用来支持函数重载和类型安全连接.由于编译后的名字不同,C++程序不能直接调用C 函数.C++提供了一个C 连接交换指定符号extern"C"来解决这个问题. 例如: extern "C&

c c++ 函数调用-C/C++ 重复调用一个函数后,传入的值为空

问题描述 C/C++ 重复调用一个函数后,传入的值为空 clac_card() { b1[]="123"; b2[]="456"; ........ rc=a(b1, c1); rc=a(b2, c2); ........ } int a(char *b,char *c) { printf("%s",b); return 0; } 打印时:b1 有值,b2为空: 有人知道为什么吗? 解决方案 我把你的代码完善一下能运行,但没发现错误呀! #inc

对象-oc 类的继承的实质,以及是怎样调用方法 和函数的

问题描述 oc 类的继承的实质,以及是怎样调用方法 和函数的 父类里声明的属性,会生成默认生成一个私有的成员变量.即不能被子类访问,那么子类通过继承得到了父类的属性,只能通过setter 和 getter 方法区访问父类的私有变量,那么这个私有变量不属于子类,那么在实例化这个子类的时候就没有这个私有变量,那么通过继承过来的setter 和getter方法访问的是什么,私有变量根本就没有生成啊! 同理在使用{}声明的私有变量同样可以在提供外部接口让外部访问,但是当子类继承后也可以通过生成实例对象,

c#调用DLL回调函数问题,硬盘录像机,NetSdk.dll,H264_DVR

问题描述 c#调用DLL回调函数问题,硬盘录像机,NetSdk.dll,H264_DVR 最近使用C#编写一个摄像头的本地监控及录像程序,硬件开发商把所有的功能实现封装到DLL里了,我通过C#调用之. 具体要实现的功能如下: 1.摄像头通过DAS功能,主动向监控主机的IP发送数据. 2.监控主机监听固定端口,处理接收到的数据. 我自己的思路: 1.新建一个Dictionary存储已上线设备的信息. 2.程序初始化H264_DVR_Init(DisCallback, 0),DisCallback为

keil 调用my_itoa多次后,程序自动HardFault_Handler 错误

问题描述 keil 调用my_itoa多次后,程序自动HardFault_Handler 错误 代码如下: int main(void) { struct tm time; uint8_t year[256],mon[256],mday[256],hour[256], min[256],sec[256]; time = Time_GetCalendarTime();//(获得日历时间) my_itoa(time.tm_year,year,10); my_itoa(time.tm_mday,mda

javascript-js 一个全局变量,在一个函数中进行赋值,调用另一个函数 ,这个全局变量的值却没有值为undined

问题描述 js 一个全局变量,在一个函数中进行赋值,调用另一个函数 ,这个全局变量的值却没有值为undined var typer; function zhe(){ typer = 'spline'; search(); } function search() { var jsonXData = []; var jsonyD = []; $.ajax({ url : base + '/gateBrandCount/statisticsbySpecial.html', data : $('#for

PL/SQL --&amp;gt; 动态SQL调用包中函数或过程

      动态SQL主要是用于针对不同的条件或查询任务来生成不同的SQL语句.最常用的方法是直接使用EXECUTE IMMEDIATE来执行动态SQL语句字符串或字符串变量.但是对于系统自定义的包或用户自定的包其下的函数或过程,不能等同于DDL以及DML的调用,其方式稍有差异.如下见本文的描述.       有关动态SQL的描述,请参考:           PL/SQL --> 动态SQL           PL/SQL --> 动态SQL的常见错误   1.动态SQL调用包中过程不正确

c语言-C语言调用abc(b,8);后数组元素为何没有改变

问题描述 C语言调用abc(b,8);后数组元素为何没有改变 #include "stdio.h" void abc(int a[],int n) { int i,t; for(i=0;i<n;i++) { t=a[i]; a[i]=a[n-1-i]; a[n-1-i]=t; } } main() { int b[10]={1,2,3,4,5,6,7,8,9,10}; int i,s=0; abc(b,8); // for(i=0;i<10;i++) // printf(&

C#调用带有回调函数的DLL的问题 !!!!急!!!!!!

问题描述 //------------dll中的回调函数---------------voidkinescope(void(*kines)(floatx,floaty)){D3DXVECTOR3vec=d3d->GetCamera()->GetPos();kines(vec.x,vec.y); //----------------C#中调用代码---------------//------------委托声明-------------publicdelegatevoidkinds(floatx