赫夫曼树输出赫夫曼编码不知道运作总是中断
赫夫曼树输出赫夫曼编码不知道运行总是中断?
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define M 10
#define N 100
typedef struct{
char data;
int weight;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char * *HuffmanCode;
void Select(HuffmanTree HT,int j,int &s1,int &s2){
int k;
int min1=100;
int min2=100;
for( k=1;k<=j;k++)
if (HT[k].weight<min1&&HT[k].parent==0)
{
min1=HT[k].weight;
s1=k;
}
for(k=1;k<=j;k++)
if (HT[k].weight<min2&&HT[k].parent==0&&k!=s1)
{
min2=HT[k].weight;
s2=k;
}
}
void Huffman(HuffmanTree &HT,HuffmanCode &HC,char a[M],int w[M],int n){
int i,m,f,s1,s2;
int c,start;
char cd[N];
HuffmanTree p;
if(n<=1)
return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for (i=1,p=HT+1;i<=n;++i,++p)
{
HT[i].data=a[i-1];
HT[i].weight=w[i-1];
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for (;i<=m;++i,++p)
{
HT[i].weight=0;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
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;
}
HC=(HuffmanCode)malloc((n+1)*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';
else
cd[--start]='1';
HC[i]=(char *)malloc((n-start)*sizeof(char));
strcpy(HC[i],&cd[start]);
}
free(cd);
}
void main(){
HuffmanTree Ht;
HuffmanCode Hc;
int n=10;
char a[M]={'a','b','c','d','e','f','g','h','i','j'};
int w[M]={1,2,3,4,5,6,7,8,9,10};
Huffman(Ht,Hc,a,w,n);
for (int i=1;i<=n;i++)
{
printf("%c :",Ht[i].data);
printf("%c",Hc[i]);
printf("\n");
}
}
------解决方案--------------------
重点检查数组越界没有,设置断点,单步调试
------解决方案--------------------
调试其实不难,最简单的就是断点跟踪,然后在下面的窗口中观察值的变化,和你的预期结果比较什么的。VS下还是很容易,有空多学一下。
------解决方案--------------------
cd是个数组,不用你free,
需要free的是申请的堆内存
------解决方案--------------------
如果现在会不会调试没事, 可以慢慢学,
但是一定得学, 因为作为程序员, 这是一个很基础, 但是非常重要的能力.
就算是那些牛得掉渣的 大神们, 也同样要调试程序的.
VS系列中:
选中一条语句 按 F9 即可添加断点. 然后按F5调试运行, 到断点后,按F10单步执行(即一次执行一条语句). 如果遇到函数调用, 可以按F11进入函数内部.
每执行一句, 鼠标移动到相关变量上看其值, 是否符合你想像的结果.
------解决方案--------------------
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。
判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
------解决方案--------------------
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试是程序员必须掌握的技能之一。
------解决方案--------------------
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define M 10
#define N 100
typedef struct{
char data;
int weight;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char * *HuffmanCode;
void Select(HuffmanTree HT,int j,int &s1,int &s2){
int k;
int min1=100;
int min2=100;
for( k=1;k<=j;k++)
if (HT[k].weight<min1&&HT[k].parent==0)
{
min1=HT[k].weight;
s1=k;
}
for(k=1;k<=j;k++)
if (HT[k].weight<min2&&HT[k].parent==0&&k!=s1)
{
min2=HT[k].weight;
s2=k;
}
}
void Huffman(HuffmanTree &HT,HuffmanCode &HC,char a[M],int w[M],int n){
int i,m,f,s1,s2;
int c,start;
char cd[N];
HuffmanTree p;
if(n<=1)
return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for (i=1,p=HT+1;i<=n;++i,++p)
{
HT[i].data=a[i-1];
HT[i].weight=w[i-1];
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for (;i<=m;++i,++p)
{
HT[i].weight=0;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
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;
}
HC=(HuffmanCode)malloc((n+1)*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';
else
cd[--start]='1';
HC[i]=(char *)malloc((n-start)*sizeof(char));
strcpy(HC[i],&cd[start]);
}
free(cd);
}
void main(){
HuffmanTree Ht;
HuffmanCode Hc;
int n=10;
char a[M]={'a','b','c','d','e','f','g','h','i','j'};
int w[M]={1,2,3,4,5,6,7,8,9,10};
Huffman(Ht,Hc,a,w,n);
for (int i=1;i<=n;i++)
{
printf("%c :",Ht[i].data);
printf("%c",Hc[i]);
printf("\n");
}
}
------解决方案--------------------
重点检查数组越界没有,设置断点,单步调试
------解决方案--------------------
调试其实不难,最简单的就是断点跟踪,然后在下面的窗口中观察值的变化,和你的预期结果比较什么的。VS下还是很容易,有空多学一下。
------解决方案--------------------
free(cd);
cd是个数组,不用你free,
需要free的是申请的堆内存
------解决方案--------------------
如果现在会不会调试没事, 可以慢慢学,
但是一定得学, 因为作为程序员, 这是一个很基础, 但是非常重要的能力.
就算是那些牛得掉渣的 大神们, 也同样要调试程序的.
VS系列中:
选中一条语句 按 F9 即可添加断点. 然后按F5调试运行, 到断点后,按F10单步执行(即一次执行一条语句). 如果遇到函数调用, 可以按F11进入函数内部.
每执行一句, 鼠标移动到相关变量上看其值, 是否符合你想像的结果.
------解决方案--------------------
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。
判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]
srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
b[(a=rand()%11)]=0;
Sleep(100);
b[(a=rand()%11)]=1;
Sleep(100);
b[(a=rand()%11)]=2;
Sleep(100);
b[(a=rand()%11)]=3;
Sleep(100);
b[(a=rand()%11)]=4;
Sleep(100);
}
return 0;
}
------解决方案--------------------
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试是程序员必须掌握的技能之一。
------解决方案--------------------