C语言数据结构迷宫实验报告,数据结构c语言课程设计报告之迷宫

本文档详述了一位学生使用C语言进行迷宫求解的课程设计过程,包括需求分析、概要设计、详细设计、测试及使用说明。设计中实现了非递归和递归两种算法,以链表作为栈数据结构,通过输入迷宫地图、起点和终点,输出解谜路径。在遇到问题时,通过改进算法解决了路径方向的表示。课程设计总结强调了理论与实践结合的重要性,以及在编程中不断学习和积累的必要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

41528d3028836879cd698677c3999917.gif数据结构c语言课程设计报告之迷宫

C语言与数据结构课程设计报告学 号 ** 姓 名 ** 课程设计题目 迷 宫 求 解 2012 年 5 月目 录1 需求分析 1.1 功能与数据需求 1.1.1 题目要求的功能 1.1.2 扩展功能 1.2 界面需求 1.3 开发环境与运行需求 2 概要设计 2.1主要数据结构2.2程序总体结构2.3各模块函数说明3 详细设计3.1算法分析与设计3.2主要程序段设计4 测试5 使用说明5.1应用程序功能的详细说明5.2应用程序运行环境要求5.5输入数据类型、格式和内容限制6 总结提高6.1课程设计总结6.2开发中遇到的问题和解决方法6.3 对自己完成课设完成情况的评价6.4《C 语言与数据结构课程设计》课程的意见与建议附录:程序源代码1 需求分析 1.1 功能与数据需求 迷宫求解问题描述:以一个 m×n的长方形表示迷宫,0 和 1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。1.1.1 题目要求的功能 基本要求:首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j )指示迷宫中的一个坐标,d 表示走到下一坐标的方向。如:对于下列数据的迷宫,输出的一条通路为:(1,1,1), (1,2,2 ), (2,2,2)(3,2,3), ( 3,1,2),…。测试数据:迷宫的测试数据如下:左上角(1,1)为入口,右下角(9,8)为出口。1 2 3 4 5 6 7 81.1.2 扩展功能(1)编写递归形式的算法,求得迷宫中所有可能的通路;(2)以方阵形式输出迷宫及其通路1.2 界面需求请求输入进入程序0 0 1 0 0 0 1 00 0 1 0 0 0 1 00 0 0 0 1 1 0 10 1 1 1 0 0 1 00 0 0 1 0 0 0 00 1 0 0 0 1 0 10 1 1 1 1 0 0 11 1 0 0 0 1 0 11 1 0 0 0 0 0 0请求输入起始位置请求输入终点位置输出方阵迷宫输出路径输出方阵路径1.3 开发环境与运行需求Visual C++6.02 概要设计 2.1主要数据结构定义模块 函数模块 主函数输入起始位置,终点位置 判断首节点是否为通路判断路径能否走通对坐标标记 是否到达迷宫出口处左边是否存在通路 下边是否存在通路 右边是否存在通路 上边是否存在通路存储路径,将路径入栈 有解迷宫 无解迷宫 YNYNY输出迷宫 选择路径 2.3各模块函数说明typedef struct{ int pos_x[length];//进栈坐标int pos_y[length];int top; int base; }Stack; //新建结构体void initStack(Stack *p) //初始化栈Push(Stack *p,int x,int y,int d) //入栈具体操作 Pop(Stack *p,int read[2],int d) //出栈并读出前一步的坐标 initMaze(int Maze[10][9])//建立迷宫Ways(Stack *p,int Maze[10][9],int rukou_x,int rukou_y,int chukou_x,int chukou_y,int d) //具体路径的求解 menu();//调用菜单函数 main();//实现迷宫求解的主函数3 详细设计迷宫的过程可以模拟为一个搜索的过程:每到一处,总让它按左、右、上、下 4个方向顺序试探下一个位置;如果某方向可以通过,并且不曾到达,则前进一步,在新位置上继续进行搜索;如果 4方向都走不通或曾经到达过,则退回一步,在原来的位置上继续试探下一位置。每前进或后退一步,都要进行判断:若前进到了出口处,则说明找到了一条合适的通路;若退回到了入口处,则说明不存在合法的通路到达出口。用一个二维指针数组迷宫表示迷宫,数组中每个元素取值“0”(表示通路)或“1”(表示墙壁)。迷宫的入口点在位置(1,1)处,出口点在位置(m,n)处。设计一个模拟走迷宫的算法,为其寻找一条从入口点到出口点的通路。二维数组的第 0行、第 m+1行、第 0列、第 m+1列元素全置成“1”, 表示迷宫的外墙;第 1行第1列元素和第 m行第 m列元素置成“0”, 表示迷宫的入口和出口;假设当前所在位置是(x,y)。沿某个方向前进一步,它可能到达的位置最多有 4。4 测试5 使用说明5.1应用程序功能的详细说明按提示输入数字 1进入迷宫,输入迷宫入口,迷宫出口5.2应用程序运行环境要求Microsoft Visual C++6.05.5输入数据类型、格式和内容限制输入的数据都是整型(int),输入迷宫的数据间要用空格或回车隔开6 总结提高6.1课程设计总结要能很好的掌握编程,仅仅通过简单的程序的编写是无法达成的,需要大量积累和深入研究才有可能。就从这个迷宫问题求解来说,在迷宫求路径就需要使用链表的栈,靠出栈和进栈来存取路径数据.在程序的编写中也不能一味的向已有的程序进行模仿,而要自己摸索,去寻找最好的解决方法,只有带着问题去反复进行实践,才能更熟练的掌握和运用,当然,对现有的程序也要多去接触,因为有些程序是我们无法在短时间内想出来的.最重要的一点是持之以恒,要经常性的复习原来接触的程序,这样才能保证我们有足够的经验去面对程序问题.6.2开发中遇到的问题和解决方法问题: 在开始时迷宫求解的 路径无法显示寻找路径所走的方向等问题。解决方法:在栈中增加一个变量 d来表示方向,在寻找路径的时候判断下一个坐标点和本坐标点的关系。在(x)行不变的情况下:(y+1)列加一则表示坐标往右走了一步记为 1、(y-1)列减一则表示坐标往左走了一步记为 3;在(y)不变的情况下:(x+1)行加一则表示坐标往下走了一步记为 2、(x-1)行减一则表示坐标往上走了一步记为 4;6.3 对自己完成课设完成情况的评价经过本次课程设计,我深刻地明白了理论与实践应用相结合的重要性,并努力克服自己在分析复杂问题的弱点。这次课程设计同时也考验我的综合运用所学知识的能力和操作能力。参考用书:《数据结构(C 语言)》,严蔚敏、吴伟民等,清华大学出版社,2010 年《数据结构与算法分析(c++语言描述)》第 2 版,黄达民编著,清华大学出版社 2006.116.4《C 语言与数据结构课程设计》课程的意见与建议希望老师能指导我们把所有的课程设计题目都做一遍,因为每一道题目所能体现的知识点是有限的,而且要想提高我们的编程能力还需要大量的练习。附录:程序源代码#inc

C语言版课程设计 #include #include 产生随机数 #include 调用计算时间的函数 #include using namespace std; 产生随机数,输入产生随机数的个数,范围,即可产生待排数据 void Random(long p[],long n,long a,long b) { long max,min; if(a>b) { max=a-b+1; min=b; } else { max=b-a+1; min=a; } srand((unsigned)time(NULL)); for(long i=1;i<=n;i++) p[i]=rand()%max+min; } 输出排序后的结果;用已检测排序的正确,是否能正确排序 void Print(long p[],long n) { cout<<"\n排序后的结果:"; for(long i=1;i<=n;i++) cout<<p[i]<<' '; } void Initiate(long p[],long q[],long n) { for(long i=1;i<=n;i++) q[i]=p[i]; } 直接插入排序:排序并测试排序过程中的时间消耗 void StraightInsertionSort(long p[],long n) { long *q=new long[n+1]; Initiate(p,q,n); LARGE_INTEGER m_liPerfFreq={0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart={0}; QueryPerformanceCounter(&m_liPerfStart); for(long i=2;i<=n;++i) if(q[i]<q[i-1]) { q[0]=q[i]; q[i]=q[i-1]; for(long j=i-2;q[0]<q[j];--j) q[j+1]=q[j]; q[j+1]=q[0]; } LARGE_INTEGER liPerfNow={0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; // Print(q,n); cout<<"\n直接插入排序时间消耗:"<<time<<" MS"; delete []q; } 折半插入排序:排序并测试排序过程中的时间消耗 void BinaryInsertionSort(long p[],long n) { long *q=new long[n+1]; Initiate(p,q,n); LARGE_INTEGER m_liPerfFreq={0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart={0}; QueryPerformanceCounter(&m_liPerfStart); for(long i=2;i<n;i++) { q[0]=q[i]; long low=1; long high=i-1; while(low<=high) { long m=(low+high)/2; if(q[0]=high+1;--j) q[j+1]=q[j]; q[high+1]=q[0]; } LARGE_INTEGER liPerfNow={0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; // Print(q,n); cout<<"\n折半插入排序时间消耗:"<<time<<" MS"; delete []q; } 希尔排序:排序并测试排序过程中的时间消耗 void ShellInsert(long q[],long dk,long n) { for(long i=dk+1;i<=n;i++) { if(q[i]0&&(q[0]<q[j]);j-=dk) q[j+dk]=q[j]; q[j+dk]=q[0]; } } } void ShellSort(long p[],long n) { long *q=new long[n+1]; Initiate(p,q,n); LARGE_INTEGER m_liPerfFreq={0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart={0}; QueryPerformanceCounter(&m_liPerfStart); long t=log(n-1)/log(2); for(long k=1;k<=t;k++) { long dk=1; for(long i=1;i<=t-k;i++) { dk=dk*2; } if(t!=k) dk+=1; ShellInsert(q,dk,n); } LARGE_INTEGER liPerfNow={0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; Print(q,n); cout<<"\n希尔排序时间消耗:"<<time<<" MS"; delete []q; } 冒泡排序:排序并测试排序过程中的时间消耗 void BubbleSort(long p[],long n) { long *q=new long[n+1]; Initiate(p,q,n); LARGE_INTEGER m_liPerfFreq={0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart={0}; QueryPerformanceCounter(&m_liPerfStart); for(long j=1;j<=n;j++) for(long i=1;iq[i+1]) { long t=q[i]; q[i]=q[i+1]; q[i+1]=t; } // Print(q,n); LARGE_INTEGER liPerfNow={0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; // Print(q,n); cout<<"\n冒泡排序时间消耗:"<<time<<" MS"; delete []q; } 双向起泡排序:排序并测试排序过程中的时间消耗 void BubbleSort_2(long p[],long n) { long *q=new long[n+1]; Initiate(p,q,n); LARGE_INTEGER m_liPerfFreq={0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart={0}; QueryPerformanceCounter(&m_liPerfStart); long low=0; long high=n; int change=1; while(low<high&&change) { change=0; for(long i=low;iq[i+1]) { long t=q[i]; q[i]=q[i+1]; q[i+1]=t; change=1; } high--; for(i=high;i>low;i--) if(q[i]<q[i-1]) { long t=q[i]; q[i]=q[i+1]; q[i+1]=q[i]; change=1; } low++; } LARGE_INTEGER liPerfNow={0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; // Print(q,n); cout<<"\n双向起泡排序时间消耗:"<<time<<" MS"; delete []q; } 递归形式的快速排序:排序并测试排序过程中的时间消耗 long Partition(long a[],long low,long high) { int m=a[low]; while(low<high) { while(low=m) --high; a[low]=a[high]; while(low<high&&a[low]<=m) ++low; a[high]=a[low]; } a[low]=m; return low; } void Qsort(long a[],long low,long high) { if(low<high) { int pivotloc=Partition(a,low,high); if(pivotloc-low<high-pivotloc)//改进后的快速排序效率确实提高了 { //先对长度短的那一部分进行排序 Qsort(a,low,pivotloc); Qsort(a,pivotloc+1,high); } else { Qsort(a,low,pivotloc); Qsort(a,pivotloc+1,high); } } } void QuickSort(long p[],long n) { long *q=new long[n+1]; Initiate(p,q,n); LARGE_INTEGER m_liPerfFreq={0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart={0}; QueryPerformanceCounter(&m_liPerfStart); Qsort(q,1,n); LARGE_INTEGER liPerfNow={0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; // Print(q,n); cout<<"\n快速排序时间消耗:"<<time<<" MS"; delete []q; // Print(q,n); } 非递归形式的快速排序:用栈的性质 void QuickSort(long p[],long left,long right) { long *q=new long[right-left+2]; Initiate(p,q,right-left+1); struct Stack { long left; long right; }; Stack S[99999]; long top=-1,i,j,start,end,temp; if(left0) { start=S[top].left; end=S[top].right; top--; long pivot=q[start]; i=start; j=end; for(; ;) { while(i<j&&q[i]<=pivot) i++; while(i<j&&pivot<q[j]) j--; if(i<j) { temp=q[i]; q[i]=q[j]; q[j]=temp; i++; j--; } else break; } q[j]=pivot; if(start<i-1) { top++; S[top].left=start; S[top].right=i-1; } if(i+1<end) { top++; S[top].left=i-1; S[top].right=end; } } } Print(q,right-left+1); } 简单选择排序:排序并测试排序过程中的时间消耗 void SelectSort(long p[],long n) { long *q=new long[n+1]; Initiate(p,q,n); LARGE_INTEGER m_liPerfFreq={0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart={0}; QueryPerformanceCounter(&m_liPerfStart); for(long i=1;i<=n;i++) { long k=i; for(long j=i+1;j<=n;j++) if(q[j]<q[k]) k=j; long t=q[k]; q[k]=q[i]; q[i]=t; } LARGE_INTEGER liPerfNow={0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; // Print(q,n); cout<<"\n简单选择排序时间消耗:"<<time<<" MS"; delete []q; } 堆排序:排序并测试排序过程中的时间消耗 void HeapAdjust(long q[],long s,long m) { long rc=q[s]; for(long j=2*s;j<=m;j*=2) { if(j<m&&q[j]=q[j]) break; q[s]=q[j]; s=j; } q[s]=rc; } void HeapSort(long p[],long n) { long *q=new long[n+1]; Initiate(p,q,n); LARGE_INTEGER m_liPerfFreq={0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart={0}; QueryPerformanceCounter(&m_liPerfStart); or(long i=n/2;i>0;i--) HeapAdjust(q,i,n); for(i=n;i>1;i--) { long t=q[1]; q[1]=q[i]; q[i]=t; HeapAdjust(q,1,i-1); } LARGE_INTEGER liPerfNow={0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; // Print(q,n); cout<<"\n堆排序时间消耗:"<<time<<" MS"; delete []q; } 基数排序:排序并测试排序过程中的时间消耗 void RadixSort(long p[],long n,int radix) { struct Radix 基数排序数据结构体 { long rc; Radix * next; }; long *q=new long[n+1]; Initiate(p,q,n); int L=1; Radix * head[11],* tail[11]; Radix * p1,* p2; LARGE_INTEGER m_liPerfFreq={0}; QueryPerformanceFrequency(&m_liPerfFreq); LARGE_INTEGER m_liPerfStart={0}; QueryPerformanceCounter(&m_liPerfStart); for(int t=1;t<=radix;t++) { for(int k=0;knext=0; tail[k]=head[k]; } for(long i=1;irc=q[i]; p1->next=0; p2=head[k]; while(p2->next!=0) p2=p2->next; p2->next=p1; tail[k]=p1; } for(k=0;k<10;) { for(long j=k+1;jnext) { // tail[k]->next=head[j]->next; // k=j; break; } tail[k]->next=head[j]->next; k=j; } p1=head[0]->next; i=1; while(p1) { q[i]=p1->rc; p1=p1->next; i++; } L*=10; } LARGE_INTEGER liPerfNow={0}; QueryPerformanceCounter(&liPerfNow); double time=liPerfNow.QuadPart - m_liPerfStart.QuadPart; time/=m_liPerfFreq.QuadPart; /* Print(q,n);*/ cout<<"\n基数排序时间消耗:"<<time<<" MS"; delete []q; } int main() 主函数 { char choice; do{ cout<<"排序时间消耗测试\n"; cout<>n>>a>>b; long *p=new long[n+1]; Random(p,n,a,b); // cout<<"产生的随机数:"; // for(int i=1;i<=n;i++) // cout<<p[i]<b) b=a; int radix=0; while(b) { b=b/10; radix++; } StraightInsertionSort(p,n);//直接插入排序 BinaryInsertionSort(p,n);//折半插入排序 // ListInsertionSort(p,n);//表插入排序 ShellSort(p,n);//希尔排序 QuickSort(p,n);//快速排序 // QuickSort(p,1,n); BubbleSort(p,n);//冒泡排序 BubbleSort_2(p,n);//双向起泡排序 SelectSort(p,n);//简单选择排序 HeapSort(p,n);//堆排序 RadixSort(p,n,radix);//基数排序 delete []p; cout<>choice; }while(choice=='Y'||choice=='y'); return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值