《数据结构》实训代码.docx
- 文档编号:8274179
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:29
- 大小:100.81KB
《数据结构》实训代码.docx
《《数据结构》实训代码.docx》由会员分享,可在线阅读,更多相关《《数据结构》实训代码.docx(29页珍藏版)》请在冰豆网上搜索。
《数据结构》实训代码
实训1哈夫曼编码/译码器
【详细设计】
(1)Read函数
Read函数用以统计文本中字符出现的频率,其函数实现如下。
首先设置一个字符型全局数组a,存放文本中可能出现的字符,假如文本中只出现字母和数字,则可设a[36]="abcdcfehijklmnopqrstuvwxyz0123456789"。
另外再设置一个整型数组weight[36],各分量都初始化为0,如果文本中出现某一字符则将其相应分量加1,例如若出现字符b则weight[1]加1,出现0则weight[26]加1。
再设置一个字符数组str[36]和整型数组w[36]。
str数组存入文本中出现的字符,w存放对应字符出现的次数,若某字符不出现则不存储。
函数具体实现如下:
voidread(){
FILE*in;inti;charc;intk1,j1;//变量定义
if((in=fopen(infile,"r"))==NULL){//打开指定的文件
printf("File(infile)notfound\n");
exit(0);
}
while(!
feof(in)){//从文件中依次取得单个字符,与数组a进行比较
c=getc(in);//得到单个字符的权值
for(i=0;i<36;i++){
if(c==a[i])weight[i]++;
}
}
for(k1=0,j1=0;k1<36;k1++){//将文件中出现的字符及其权值分别存入
if(weight[k1]!
=0){//另一个数组,以获得其对应关系
str[j1]=a[k1];
w[j1]=weight[k1];
++j1;}
}
length=j1;//计算文件的长度
fclose(in);//关闭文件
}
(2)Huffmancoding函数的设计
哈夫曼编码函数Huffmancoding按照字符出现的次数生成对应的哈夫曼编码。
哈夫曼编码函数按照第6章所学的算法进行设计,主要实现了几个类C语言的语句和Select函数,其函数流程图如图10-1所示。
函数具体实现如下:
voidHuffmanCoding(HuffmanTree&HT,int*w,intn){
//w存放n个字符的权值,构造huffman树HT,并求n个字符的huffman编码HC
inti,j,s1,s2,f,m1,m2;
intm,start,c;
HuffmanTreep;
char*cd;
if(n<=1)return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for(p=HT+1,i=1;i<=n;++i,++p,++w){//*p={*w,0,0,0,0);
p->weight=*w;
p->flag=0;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(;i<=m;++i,++p){//*p={0,0,0,0,0};
p->weight=0;
p->flag=0;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(i=n+1;i<=m;++i){//建huffman树
//Select(HT,i-1,s1,s2);
m1=m2=1000;//MaxWeightValue
s1=s2=0;
for(j=0;j
if(HT[j].weight m2=m1; s2=s1; m1=HT[j].weight; s1=j; //printf("%d\n",m1); } elseif(HT[j].weight m2=HT[j].weight; s2=j; //printf("%d\n",m2); } } HT[s1].parent=i; HT[s2].parent=i; HT[s1].flag=1; HT[s2].flag=1; HT[i].lchild=s1; HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//分配n个字符的头指针向量 cd=(char*)malloc(n*sizeof(char));//分配求编码的工作空间 cd[n-1]='\0';//编码结束符 for(i=1;i<=n;++i){//逐个字符求huffman编码 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'; elsecd[--start]='1'; HC[i]=(char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间 strcpy(HC[i],&cd[start]);//从cd复制编码到HC } free(cd);//释放工作空间 } (3)Write函数的设计 Write函数依次从待编译的文本文件中读取一个字符,按照生成的哈夫曼编码转化成对应的二进制编码,存入到cod文件中去。 函数具体实现如下: voidwrite(){ FILE*fp;FILE*in;inti,j;charc; if((fp=fopen(outfile,"w"))==NULL){//打开待写入的二进制文件 printf("File(outfile)notfound\n"); exit(0);//若文件不存在,则报错,并中断程序的执行 } if((in=fopen(infile,"r"))==NULL){//打开待读入的文本文件 printf("File(infile)notfound\n"); exit(0);//若文件不存在,则报错,并中断程序的执行 } while(! feof(in)){//分别对单个字符进行编码 c=getc(in); for(i=0;i j=0; if(c==str[i]) while(HC[i+1][j]! ='\0'){//写入huffman编码 fprintf(fp,"%c",HC[i+1][j]); j++; } } } fclose(in);//关闭读出文件 fclose(fp);//关闭写入文件 } (4)Trans函数的设计 Trans函数的功能是从二进制的cod文件中读入二进制字符串,根据哈夫曼编码将其转化为相应的字符。 其函数流程图如图10-2所示。 函数具体实现如下: voidtrans(HuffmanTreeHT,intn){ intm;charc;FILE*fp,*fp1; if((fp1=fopen(outfile,"r"))==NULL){//打开待读文件 //若文件不存在,则报错,并中断程序的执行 printf("File(outfile)notfound\n"); exit(0); } fp=fopen("out.txt","w");//建立写入文件out.txt m=2*n-1;//m指向哈夫曼树的根结点 while(! feof(fp1))//未到文件尾部,则循环 { c=fgetc(fp1);//从文件中读入一字符到c if(c=='0') m=HT[m].lchild;//c为'0',则m指向左孩子 else m=HT[m].rchild;//否则m指向右孩子 if(HT[m].lchild==0&&HT[m].rchild==0){ //若当前m所指为叶子,则将该叶子对应的字符写到文件 fputc(str[m-1],fp); m=2*n-1;//m重新指向哈夫曼树的根结点,准备进行下一个译码 } } fclose(fp);//关闭待读文件 fclose(fp1);//关闭写入文件 } (5)界面显示函数的设计 主界面和编码解码界面结构简单,在此给出其实现函数。 主函数的具体实现如下: voidmain(){ intpi; loop: system("cls");//调用dos命令清屏 system("color2f");//改变界面颜色 printf("\n\n请选择要登陆的界面: \n\n"); printf("1.编码界面\n\n"); printf("2.解码界面\n\n"); printf("3.退出\n\n\n"); printf("请选择序号: "); scanf("%d",&pi); if(pi==1){//进入编码界面 system("cls");//调用dos命令清屏 codingscreen(); getchar();//进行延时,只有再次敲击键盘才能继续运行 getchar();//同上 } if(pi==2){//进入译码界面 system("cls");//清屏 transscreen(); getchar();//等待敲击键盘,实际上起到延时功能 } if(pi==3){//退出 system("exit"); return; } gotoloop; } 编码函数的具体实现如下: voidcodingscreen(){//定义编码界面 FILE*in1;FILE*fp;inti,k;charch,c; HuffmanTreeHT; printf("\n\n****************Huffman编码界面*****************\n\n"); for(i=1;i<10;i++) {printf("(%d)NO%d.txt(%d)NO%d.txt\n",i,i++,i+1,i+1);} printf("\n请选择编码文件序号: "); scanf("%d",&k); printf("\n你选择的是NO%d.txt\n\n",k); switch(k){//获得选择的文件名称,对infile,outfile赋值 case1: strcpy(infile,"NO1.txt");strcpy(outfile,"NO1.cod");break; case2: strcpy(infile,"NO2.txt");strcpy(outfile,"NO2.cod");break; } read(); HuffmanCoding(HT,w,length); write(); printf("***************Huffman编码结束**********\n"); fclose(in1); fclose(fp); } 译码函数的具体实现如下: voidtransscreen(){ FILE*in1;FILE*fp;inti,k;charch,c; HuffmanTreeHT; printf("\n\n**************Huffman译码程序**************\n\n"); for(i=1;i<10;i++) {printf("(%d)NO%d.cod(%d)NO%d.cod\n",i,i++,i+1,i+1);} printf("\n请选择译码文件序号: "); scanf("%d",&k); printf("\n你选择的是NO%d.cod\n",k); switch(k){//获得选择的文件,同时对infile,outfile赋值 case1: strcpy(infile,"NO1.txt");strcpy(outfile,"NO1.cod");break; case2: strcpy(infile,"NO2.txt");strcpy(outfile,"NO2.cod");break; } read();//哈夫曼编码在实际应用中采用传输的方式 HuffmanCoding(HT,w,length); printf("\n"); write(); trans(HT,length); printf("*************Huffman译码结束*************\n"); fclose(in1); fclose(fp); } 实训2内部排序 【详细设计】 首先我们使用了线程对应各自的算法: UINTThreadSortBubble(LPVOIDlp) UINTThreadSortQuick(LPVOIDlp) UINTThreadSortSelect(LPVOIDlp) UINTThreadXier(LPVOIDlp) UINTThreadDui(LPVOIDlp) UINTThreadCharu(LPVOIDlp) 获得当前视图的数组头地址: data=pView->m_SortBubble; 比较次数采用下述的变量名: maopaocishu; kuaisucishu; xuanzecishu; xiercishu; duicishu; charucishu; 下面是菜单选项对应的响应函数: voidCEx29View: : OnSortBubble(){//冒泡排序 IsSortBubble=TRUE; AfxBeginThread(ThreadSortBubble,GetSafeHwnd()); } voidCEx29View: : OnSortQuick(){//快速排序 IsSortQuick=TRUE; AfxBeginThread(ThreadSortQuick,GetSafeHwnd()); } voidCEx29View: : OnSortSelect(){//选择排序 IsSortSelect=TRUE; AfxBeginThread(ThreadSortSelect,GetSafeHwnd()); } voidCEx29View: : OnXier(){//希尔排序 IsSortXier=TRUE; AfxBeginThread(ThreadXier,GetSafeHwnd()); } voidCEx29View: : OnDui(){//堆排序 IsSortDui=TRUE; AfxBeginThread(ThreadDui,GetSafeHwnd()); } 在这几个响应函数中,GetSafeHwnd的功能是获得当前句柄;AfxBeginThread的功能启动相应的线程,并且将相应算法的启动标志置为真。 下面是主程序的构造函数: CEx29View: : CEx29View(){ inti; srand((unsigned)time(NULL));//以时间为种子进行随机数的产生 for(i=0;i m[i]=m_dui[i]=m_xier[i]=m_SortBubble[i]=m_SortQuick[i]= m_SortSelect[i]=(int)((double)rand()*100.0/(double)RAND_MAX); } pView=this; IsSortSelect=FALSE;//标志位为假,以便随时响应菜单选项的消息 IsSortQuick=FALSE; IsSortBubble=FALSE; IsSortXier=FALSE; IsSortDui=FALSE; } 图象显示函数: voidCEx29View: : OnDraw(CDC*pDC){ inti;//相应的画刷,先产生矩形,再填满颜色 CEx29Doc*pDoc=GetDocument(); ASSERT_VALID(pDoc); if (1){//源数据的显示 CBrushBlackBrush(RGB(0,0,0)); for(i=0;i mRect.bottom=470; mRect.left=490+i*2; mRect.right=mRect.left+1; mRect.top=mRect.bottom-m[i]; pDC->FillRect(&mRect,&BlackBrush); } BlackBrush.DeleteObject(); pDC->TextOut(540,500,"源数组表示图"); } if(IsSortBubble){//冒泡排序的动态显示 CBrushBlueBrush(RGB(0,0,255)); CStringss1; ss1.Format("%d",maopaocishu); pDC->TextOut(100,200,"冒泡排序次数: "+ss1); for(i=0;i m_SortBubbleRect.bottom=170; m_SortBubbleRect.left=50+i*2; m_SortBubbleRect.right=m_SortBubbleRect.left+1; m_SortBubbleRect.top=m_SortBubbleRect.bottom-m_SortBubble[i]; pDC->FillRect(&m_SortBubbleRect,&BlueBrush); } BlueBrush.DeleteObject(); } if(IsSortQuick){//快速排序的动态显示 CBrushRedBrush(RGB(255,0,0)); CStringss2; ss2.Format("%d",kuaisucishu); pDC->TextOut(320,200,"快速排序法演示次数"+ss2); for(i=0;i m_SortQuickRect.bottom=170; m_SortQuickRect.left=270+i*2; m_SortQuickRect.right=m_SortQuickRect.left+1; m_SortQuickRect.top=m_SortQuickRect.bottom-m_SortQuick[i]; pDC->FillRect(&m_SortQuickRect,&RedBrush); } RedBrush.DeleteObject(); } if(IsSortSelect){ CBrushGreenBrush(RGB(0,255,0)); CStringss3; ss3.Format("%d",xuanzecishu); pDC->TextOut(540,200,"选择排序法演示次数"+ss3); for(i=0;i m_SortSelectRect.bottom=170; m_SortSelectRect.left=490+i*2; m_SortSelectRect.right=m_SortSelectRect.left+1; m_SortSelectRect.top=m_SortSelectRect.bottom-m_SortSelect[i]; pDC->FillRect(&m_SortSelectRect,&GreenBrush); } GreenBrush.DeleteObject(); } if(IsSortXier){//希尔排序的动态显示 CBrushABrush(RGB(130,130,0)); CStringss4; ss4.Format("%d",xiercishu); pDC->TextOut(100,500,"希尔排序法演示次数"+ss4); for(i=0;i m_SortXierRect.bottom=470; m_SortXierRect.left=50+i*2; m_SortXierRect.right=m_SortXierRect.left+1; m_SortXierRect.top=m_SortXierRect.bottom-m_xier[i]; pDC->FillRect(&m_SortXierRect,&ABrush); } ABrush.DeleteObject(); } if(IsSortDui){//堆排序的动态显示 CBrushBBrush(RGB(0,100,77)); CStringss5; ss5.Format("%d",duicishu); pDC->TextOut(320,500,"堆排序法演示次数: "+ss5); for(i=0;i m_SortDuiRect.bottom=470; m_SortDuiRect.left=270+i*2; m_SortDuiRect.right=m_SortDuiRect.left+1; m_SortDuiRect.top=m_SortDuiRect.bottom-m_dui[i]; pDC->FillRect(&m_SortDuiRect,&BBrush); } BBrush.DeleteObject(); } //最终条形图结果的显示 if((end1=TRUE)&&(end2=TRUE)&&(end3=TRUE)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 代码