算法与数据结构.docx
- 文档编号:30302501
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:41
- 大小:311.35KB
算法与数据结构.docx
《算法与数据结构.docx》由会员分享,可在线阅读,更多相关《算法与数据结构.docx(41页珍藏版)》请在冰豆网上搜索。
算法与数据结构
数据结构与算法课程设计
题目排序算法比较问题;递归替换问题;跳马问题;长整数运算问题
目录
摘要4
一.排序算法比较问题5
1.采用类语言定义相关的数据类型5
2.算法设计5
3.函数的调用关系图7
4.调试分析7
5.测试结果8
6.源程序(带注释)11
二、递归替换问题15
1.采用类语言定义相关的数据类型15
2.算法分析15
3.函数调用关系图15
4.调试分析:
16
5.测试结果16
6.源程序17
三、跳马问题18
1.采用类语言定义相关的数据类型18
2.算法设计18
3.函数的调用关系图19
4.调试分析19
5.测试结果19
6.源程序(带注释)20
四、长整数运算问题22
1.采用类语言定义相关的数据类型22
2.算法设计22
3.函数调用图23
4.调试分析23
5.测试结果24
6.源程序(带注释)24
总结33
参考文献34
致谢35
摘要
第一道题是编写算法实现各种排序算法,并得出各排序算法数据比较的次数及数据交换的次数,得出各排序算法的优缺点。
在MicrosoftVisualC++或者C-Free中实现程序的调试。
通过该题目的设计过程,可以进一步理解和熟练掌握课本中所学的各种数据结构的知识,加深对排序的认识。
学会如何把学到的知识用于解决实际问题,培养自己的动手能力。
第二个程序为递归替换仿编译问题,具体要求是递归替换问题。
编写程序,扩展C/C++源文件中的#include指令(以递归的方式)。
以文件名的内容替换形预编译命令“include”。
具体是用相应文件的内容来替换上面的代码“预编译”的命令,即在最后的结果查看文件中没有“#include”字样,其位置为相应文件的内容,考虑到有可能在我们要替换的文件中也可能会有预编译命令,所以要用递归的算法。
通过这个代码的编写可以帮我们更深层次的理解c语言编译的过程,同时也能够练习递归的运用。
第三道题是跳马问题。
本课程设计主要研究如何通过给定坐标,通过国际象棋中马的跳跃规则,对棋盘上所有格子进行遍历的过程。
根据给定的坐标,通过循环,依次遍历下一级坐标,寻找出循环次数最少的下一级坐标,最终达到遍历所有格子的目标。
通过这个代码,可以使我们对循环有更好的运用。
第四道为长整数运算问题。
具体要求根据输入的任意位数的整数运算表达式,最终得出计算结果。
在这里通过栈,对数据及运算符进行存取,并进行计算最后得出结果。
通过这个代码可以使我们对栈有了更深刻的理解。
关键词:
排序算法递归替换预编译跳马循环长整数运算
一.排序算法比较问题
设计各类排序算法的程序,通过随机的数据测试,比较各算法的关键字比较次数和关键字移动次数。
1.采用类语言定义相关的数据类型
定义一个数组用来存储需要排序的一组数据
intdate[10]
2.算法设计
1.直接插入排序:
用两个循环结构为一组乱序数据进行排序。
for(i=0;i<9;i++){
for(j=i;j>=0;j--){
c1++;
if(n[j]>=n[j+1]){
w=n[j];
n[j]=n[j+1];
n[j+1]=w;
c2++;
}
}
}
2.冒泡排序:
用两个循环结构为一组乱序数据进行排序。
for(i=0;i<9;i++){
for(j=0;j<9-i;j++){
c1++;
if(a[j]>a[j+1]){
w=a[j];
a[j]=a[j+1];
a[j+1]=w;
c2++;
}
}
}
3.选择排序:
用两个循环结构为一组乱序数据进行排序。
for(i=0;i<10;i++){
k=i;
for(j=i+1;j<10;j++){
c1++;
if(a[k]>a[j]){
k=j;
}
}
t=a[i];
a[i]=a[k];
a[k]=t;
c2++;
}
4.快速排序:
通过两个索引的移动实现一组乱序数据的排序
while(left while((left right--; if(left L[left++]=L[right]; while((left left++; if(left L[right--]=L[left]; } L[left]=key; 3.函数的调用关系图 图1.1函数调用图 4.调试分析 1输入一组乱序的整数数组共10个 图1.2输入数据 5.测试结果 1图1.3为直接插入排序 图1.3直接插入排序 2图1.4为冒泡排序 图1.4冒泡排序 3图1.5为选择排序 图1.5选择排序 4图1.6为快速排序 图1.6快速排序 5结果分析: 时间复杂度直接插入O(n^2),冒泡排序O(n^2),选择排序O(n^2),快速排序O(nlogn) 6.源程序(带注释) #include intmain(){//主函数 inte=1; while(e){ inti=0; intn[10]; intc; printf("请输入10个要排序的数: \n"); for(i=0;i<=9;i++){ scanf("%d",&n[i]); } printf("-----------------------\n"); printf("1.直接插入排序\n"); printf("2.冒泡排序\n"); printf("3.选择排序\n"); printf("4.快速排序\n"); printf("0.退出\n"); printf("请选择排序算法: "); scanf("%d",&c); switch(c){ case1: direct(n);break; case2: bubble_sort(n);break; case3: choices_sort(n);break; case4: printf("\n快速排序结果: \n");quick_sort(n,0,9);break; case0: e=0;break; default: printf("输入错误"); } printf("\n按任意值继续\n"); getch(); system("cls"); } return0; } intdirect(intn[]){//直接插入排序 inti,j,w,s,c1=0,c2=0; printf("\n直接插入排序结果: \n"); for(i=0;i<9;i++){ for(j=i;j>=0;j--){ c1++; if(n[j]>=n[j+1]){ w=n[j]; n[j]=n[j+1]; n[j+1]=w; c2++; } } for(s=0;s<=9;s++){ printf("%d",n[s]); } printf("\n"); } printf("\n比较次数: %d移动次数: %d",c1,c2); return0; } intbubble_sort(inta[]){//冒泡排序 inti,j,w,s,c1=0,c2=0; printf("\n冒泡排序结果: \n"); for(i=0;i<9;i++){ for(j=0;j<9-i;j++){ c1++; if(a[j]>a[j+1]){ w=a[j]; a[j]=a[j+1]; a[j+1]=w; c2++; } } for(s=0;s<=9;s++){ printf("%d",a[s]); } printf("\n"); } printf("\n比较次数: %d移动次数: %d",c1,c2); return0; } intchoices_sort(inta[]){//选择排序 inti,j,k,t,s,c1=0,c2=0; printf("\n选择排序结果: \n"); for(i=0;i<10;i++){ k=i; for(j=i+1;j<10;j++){ c1++; if(a[k]>a[j]){ k=j; } } t=a[i]; a[i]=a[k]; a[k]=t; c2++; for(s=0;s<=9;s++){ printf("%d",a[s]); } printf("\n"); } printf("\n比较次数: %d移动次数: %d",c1,c2); return0; } intquick(intfirst,intend,intL[]){ intleft=first,right=end,key; key=L[first]; while(left while((left right--; if(left L[left++]=L[right]; while((left left++; if(left L[right--]=L[left]; } L[left]=key; returnleft; } intquick_sort(intL[],intfirst,intend){//快速排序 intsplit,i,c1=0,c2=0; if(first split=quick(first,end,L); quick_sort(L,first,split-1); quick_sort(L,split+1,end); } if(first=end){ for(i=0;i<=9;i++){ printf("%d",L[i]); } printf("\n"); } //printf("\n比较次数: %d移动次数: %d",c1,c2); return0; } 二、递归替换问题 编写程序,扩展C/C++源文件中的#include指令(以递归的方式)。 请以文件名的内容替换形如下面的代码行。 #include“filename” 1.采用类语言定义相关的数据类型 定义一个一维数组来存储文件中的内容Stringdate[],测试文件分别为file1.c,file2.c,fil3.c。 2.算法分析 通过递归函数逐行遍历文件中的内容,若该行为#include命令行则继续遍历下一行,若该行不是#include命令,则保存。 intprint(Stringfilename1){//递归遍历函数 Stringhang=getHang(filename); If(hang==”#include”){ print(filename2); }else{ save(hang); } return0; } 3.函数调用关系图 图2.1函数调用图 4.调试分析: 输入测试文件file1.c的文件名 file1.c中的内容为: #include”file2.c” a b c file2.c中的内容为: #include”file3.c” d e f file3.c中的内容为: z x c 5.测试结果 图2.2运行结果 结果分析: #include”file”语句被file文件中的内容替代 6.源程序 importjava.io.IOException; importjava.nio.file.Paths; importjava.util.Scanner; publicclassTest{ publicString[]prin(Strings){//递归函数 inti; String[]d=newString[100];//存储文件内容 try{ Scannerin=newScanner(Paths.get(s));//文件输入 while(in.hasNext()){//遍历文件内容 i=0;//判断是否为#include指令的标志0表示不是 Stringstr=in.next();//读取文件一行 char[]c=str.toCharArray(); for(charch: c){//判断是否存在#号 if(ch=='#'){ i=1; break; } } if(i==1){//如果是#include指令 String[]ss=str.split("\"");//通过“"”号拆分指令行得到下一个文件 prin(ss[1]);//进行递归 }else{//如果不是指令行 System.out.println(str);//输出该行 } } in.close(); returnd; }catch(IOExceptione){ e.printStackTrace(); } returnd; } publicstaticvoidmain(String[]args){//主方法 //String[][]d; System.out.println("测试文件file1内容: "); System.out.println("#include\"file2.c\"\na\nb\nc\n"); System.out.println("测试文件file2内容: "); System.out.println("#include\"file3.c\"\nd\ne\nf\n"); System.out.println("测试文件file3内容: "); System.out.println("\nz\nx\nc\n"); Testtest=newTest(); //d=test.d2; System.out.println("结果为: "); test.prin("file1.c"); } } 三、跳马问题 要求在64个国际象棋格子,任意位置放一个马,如何不重复地把格子走完。 。 1.采用类语言定义相关的数据类型 通过变量intx,y存储马的起始坐标,定义一个8*8的二维数组intdate[8][8]来表示所有的棋盘格子。 2.算法设计 国际象棋中马采用“日”字走法,对棋盘上任意一个马所在的结点,它所能走的结点在一步之内有八种情况,即假设马所在的坐标为(i,j),那么它能走的八个坐标分别为(i+1,j+2),(i+1,j-2),(i+2,j-1),(i+2,j+1),(i-2,j-1),(i-2,j+1),(i-1,j-2),(i-1,j+2),把这八个点个看做是(i,j)的领结点,以此类推每个结点都有邻结点,所以可采用图的深度遍历,以马所在的结点(i,j)为初始结点,对全图进行深度遍历,然后按照遍历的顺序输出结点。 最短字符串问题: 编写一个程序,从输入中读取字符串,并按长度顺序,最短字符串优先的原则输出它们。 如果有若干字符串具有相同的长度,就按字母顺序输出它们。 3.函数的调用关系图 图3.1函数调用图 4.调试分析 1任意输入2个数字作为马的起始位置 图3.2程序输入 5.测试结果 图3.3运行结果 6.源程序(带注释) #include"stdio.h" #include"windows.h" intk[8][8];//存储最终结果 voidshow(); inttravel(intx,inty); intmain()//主函数 { //定义一个数组,用于存储坐标 intx,y,i=1;//定义X,Y坐标 printf("请输入行号(0-7): "); scanf("%d",&x); printf("请输入列号(0-7): "); scanf("%d",&y); if(travel(x,y)==1){ printf("遍历成功! \n"); show(); }else{ printf("遍历失败! \n"); show(); } return0; } voidshow(){//显示遍历结果 for(inti=0;i<8;i++){ for(intj=0;j<8;j++){ printf("%3d",k[i][j]); } printf("\n\n"); } } inttravel(intx,inty){//遍历函数 intcurX,curY,endX=0,endY=0,m,tempX,tempY; inti,min,minP; curX=x; curY=y; k[curX][curY]=1; intnextX[]={-2,-1,1,2,2,1,-1,-2}; intnextY[]={1,2,2,1,-1,-2,-2,-1}; intway[]={0,0,0,0,0,0,0,0}; for(m=2;m<=64;m++){ for(inti=0;i<8;i++){ tempX=curX+nextX[i]; tempY=curY+nextY[i]; if(tempX<0||tempX>7||tempY<0||tempY>7||k[tempX][tempY]! =0){ continue; }else{ endX=tempX; endY=tempY; for(intj=0;j<8;j++){ if(tempX+nextX[j]<0||tempX+nextX[j]>7||tempY+nextY[j]<0||tempY+nextY[j]>7||k[tempX+nextX[j]][tempY+nextY[j]]! =0){ continue; }else{ way[i]++; } } } } for(i=0,min=9,minP=-1;i<8;i++){ if(way[i]==0){ continue; }elseif(min>=way[i]){ min=way[i]; minP=i; } way[i]=0; } if(minP==-1){ if(m==64){ k[endX][endY]=m; return1; }else{ return0; } }else{ curX+=nextX[minP]; curY+=nextY[minP]; k[curX][curY]=m; } } return1; } 四、长整数运算问题 设计程序,实现两个任意长的整数的加、减、乘运算问题。 1.采用类语言定义相关的数据类型 开始建立两个空的栈。 一个用来存放长整数运算的运算符。 另一个用来存放长整数数字字符。 通过调整栈内元素的进出顺序来实现长整数的加、减、乘、除四则运算。 算法设计。 系统通过建立两个空栈Stack(so)和Stack(sd)用来存放运算符和数据。 建立一个函数Getnumbersize()来获取数字字符的长度。 用一个函数Transfer()来将数字字符转换成整数数据。 然后利用if和else语句实现对从键盘采集来的字符利用栈的后进先出的性质进行判断和进出栈操作。 从而实现任意长整数的四则运算。 2.算法设计 系统建立两个空栈Stack(so)和Stack(sd)用前一个存放运算符“+”、“-”、“*”、“/”且程序规定“(”为1,“+”为2,“-”为3,“*”为4,“/”为5,“”为。 后一个存放将要进行运算的操作数。 当系统运行开始时输出“提示: 若有负数输入请用括号括起来”和“输入整数表达式(如: (1+2)*1.2/4=): ”。 用户输入一连串的字符,开始进行键盘采集。 当采集完毕时,系统开始判断运算的优先级,若为“(”则将“(”的代码1直接入到栈Stack(so)中,然后将后面的数字字符转换成整数数据入到栈Stack(sd)中。 当入栈完毕再次判断数字字符后面的运算符,若是“+”、“-”则直接将2,3入栈到Stack(so)中。 如果是“*”或“/”则进行优先级判断,看“*”(“/”)后面是不是有“(”如果有则将4(5)入到栈Stack(so)中。 如果没有则将前面的整数数据出栈与“*”(“/”)后的数字字符转换成的整数数据进行运算将结果存入定义的变量t3中然后将t3入到栈Stack(sd)中。 等到读入的数据出现“=”时确定入栈完毕。 然后按照栈的“后进先出”规则进行出栈逐步进行运算得最后结果。 3.函数调用图 图4.1函数调用图 4.调试分析 1、编译时出现的问题: ①出现的错误一般是由粗心造成的,例如: 因多重大括号而导致的大括号丢失或过多。 偶尔掉落“;”等导致系统调试时出现错误。 经系统提示都可找到错误出处并修改成功。 ②当输入数据进行测试时。 出现过比较重大的错误。 如果输入的数为负数非常容易出现数据溢出现象,得不到正确结果,例如: -12+4按照原先的结果应该是-8。 结果当运行时结果却是-16。 如果输入12-4结果和预期的一样。 但是如果第一个数是负数不论后面是什么样的数据和运算符总是得不到预期的结果。 经过反复的数据测
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 数据结构