迷宫数据结构.docx

上传人:b****4 文档编号:6661570 上传时间:2023-05-10 格式:DOCX 页数:24 大小:83.02KB
下载 相关 举报
迷宫数据结构.docx_第1页
第1页 / 共24页
迷宫数据结构.docx_第2页
第2页 / 共24页
迷宫数据结构.docx_第3页
第3页 / 共24页
迷宫数据结构.docx_第4页
第4页 / 共24页
迷宫数据结构.docx_第5页
第5页 / 共24页
迷宫数据结构.docx_第6页
第6页 / 共24页
迷宫数据结构.docx_第7页
第7页 / 共24页
迷宫数据结构.docx_第8页
第8页 / 共24页
迷宫数据结构.docx_第9页
第9页 / 共24页
迷宫数据结构.docx_第10页
第10页 / 共24页
迷宫数据结构.docx_第11页
第11页 / 共24页
迷宫数据结构.docx_第12页
第12页 / 共24页
迷宫数据结构.docx_第13页
第13页 / 共24页
迷宫数据结构.docx_第14页
第14页 / 共24页
迷宫数据结构.docx_第15页
第15页 / 共24页
迷宫数据结构.docx_第16页
第16页 / 共24页
迷宫数据结构.docx_第17页
第17页 / 共24页
迷宫数据结构.docx_第18页
第18页 / 共24页
迷宫数据结构.docx_第19页
第19页 / 共24页
迷宫数据结构.docx_第20页
第20页 / 共24页
亲,该文档总共24页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

迷宫数据结构.docx

《迷宫数据结构.docx》由会员分享,可在线阅读,更多相关《迷宫数据结构.docx(24页珍藏版)》请在冰点文库上搜索。

迷宫数据结构.docx

迷宫数据结构

 

6.源程序(带注释)………………………………………………………………11

摘要

迷宫问题的求解是一个很好的在栈或者队列等方面的应用问题,本次设计是以栈去实现的。

问题的求解主要是给定一个入口坐标和出口坐标时求出一条从入口到出口的路径,如果不存在或存在要做出相应的判断,存在时打印其路径,并做动态演示。

关键字:

栈,栈的存储结构,出栈与入栈

 

前言

 

由于计算机解迷宫时,通常用的是群举的方法,即从入口出发,顺某一方向搜索。

若能走通,则继续往前走;否则沿原路退回,换一个方向再继续搜索,直至所有可能的通路都搜索完为止。

为了保证在任何位置上都能沿原路返回,这就需要一个后进先出的结构来存储起位置,所以用到了栈的概念。

在问题的求解过程中,用到了对栈的定义、栈的初始化、栈的空间的申情、栈的销毁等有关栈的知识。

通过这次课程设计可让我们更深一步的了解栈的概念。

在解决问题的过程中初步懂的如何去选择合适的方法去处理问题,提高解决问题的效率。

 

正文

1.采用类C语言定义相关的数据类型

(1)定义坐标(X,Y)与搜索方向dir:

typedefstruct{

intx,y;

intdir;

}pos,elem;

(2)定义栈存放路径:

typedefstruct{

elem*b,*t;

intsize;

}stack;

 

2、各模块的伪码算法

(1)

voidmazerandom(inti,intj,intr)//随即产生一个n*n的迷宫

for(i=0;i

mg[i][0]=mg[i][n-1]=mg[0][i]=mg[n-1][i]=1;//设置围墙

for(j=1;j

for(r=1;r

mg[j][r]=rand()%2;

(2)

voidstep(stack*s,pos*cur,stack*reslut)//探索路径函数

{Initstack(s);curpos=start;//设定“当前位置”为“入口位置”

curstep=1;//探索第一步

do{

if(Pass(curpos))

{FootPrint(curpos);//留下足迹

e=(curstep,curpos,1);

Push(S,e);//加入路径

if(curpos==end)return(TRUE);//到达终点(出口)

curpos=NextPos(curpos,1);

curstep++;}//探索下一步

else{//当前位置不能通过

if(!

StackEmpty(s)){

pop(S,e);

while(e.di==4&&!

StackEmpty(S)){

MarkPrint(e.seat);pop(S,e);//留下不能通过的标记,并退回一步

}//while

if(e.di<4){

e.di++;Push(S,e);//换下一个方向探索

curpos=NextPos(e.seat,e.di);//设定当前位置是该新方向上的相领块

}//if

}//if

}//else

}while(!

StackEmpty(S));

return(FALSE);}//MazePath

(3)

voidsavepath(stack*s,pos*cur,stack*result)//保存路径函数

{pos*top=s->t;

if(stackempty(result))//若栈result为空

{push(result,cur);//可通路径坐标存入result栈

While(top>s->b)

Push(result,--top);}

elseif(sizeof(result)>sizeof(s))//若result栈中元素多于s栈中元素

clearstack(result);

push(result,cur);//可通路径坐标存入result栈

while(top>s->b)

push(result,--top);}//Savepath

(4)

voidprint(stack*s,pos*s,stack*result)//输出

{if(StackEmpty(result))

printf(“Nowayavailable!

”);//输出没有找到

else

while(!

StackEmpty(result))//当栈非空

{pop(result,cur);

draw(y,x);//在屏幕上绘出路径

printf(“(%d,%d)”,x,y);}}//输出路径坐标

 

3、函数关系调用图

 

 

4、调试分析

A、调试中遇到的问题既对问题的解决方案

(1)在输入迷宫的大小n时,若n太大,例如n=30,屏幕无法显示第25行以及其后的方块。

解决方法:

EXEC:

printf(“Pleaseinputthesizeofmaze(n*n):

”);

scanf(“%d”,&n);

添加语句:

if(n>24)

{printf(“\nThenumberissolarge!

Tryitagain!

\n”);

gotoEXEC;}

(2)在输入迷宫的起点与终点坐标时,若输入坐标超过迷宫的表示范围则程序立即结束并不返回任何值,若输入的坐标在迷宫的“围墙”上时,搜索依然进行,并返回路径。

解决方法:

up:

printf(“Pleaseinputthestartpath(c,d):

”);

scanf(“%d%d”,&d,&c);

printf(“Pleaseinputtheendpath(a,b):

”);

scanf(“%d%d”,&b,&a);

添加语句:

if(c>n-2||d>n-2||a>n-2||b>n-2||c==0||d==0||a==0||b==0)

{printf(“Thenumberextendtheboundar

array!

Tryitagain!

\n”);

gotoup;}

B、算法的时间复杂度和空间复杂度:

整个程序转为.EXE可执行后整体的:

空间复杂度为18.3KB

时间复杂度O(n4)

 

测试结果

a.输入迷宫大小(n*n):

b.输入起点(c,d)与终点(a,b)坐标:

 

运行结果:

 

6.源程序(带注释)

#include

#include

#include

#include

typedefstruct{/*定义结构体其中坐标(x,y)搜索方向dir*/

intx,y;

intdir;

}pos,elem;

typedefstruct{/*定义栈顶指针t栈底指针b栈的大小size*/

elem*b,*t;

intsize;

}stack;

voidinitstack(stack*s)/*定义栈的存储空间*/

{s->b=(elem*)malloc(150*sizeof(elem));

if(s->b){

s->t=s->b;

s->size=150;

return;}

exit(0);}

voidpush(stack*s,elem*e)/*数据入栈*/

{*s->t=*e;s->t++;}

voidpop(stack*s,elem*e)/*弹出栈中元素*/

{*e=*--s->t;}

voidclearstack(stack*s)/*清空栈中所有元素*/

{s->t=s->b;}

intstackempty(stack*s)/*判断栈是否为空*/

{return!

(s->t-s->b);}

intdestroystack(stack*s)/*销毁栈*/

{free(s->b);/*由系统回收栈底指针*/

free(s);/*系统回收栈s的存储空间*/

return1;}

intd,c,n,a,b,i,r,j,mg[100][100],x1,y1,dongx[100],dongy[100];doublez;

voidstep(stack*s,pos*cur,stack*result);

voidsavepath(stack*s,pos*cur,stack*result);

voiddraw(inty,intx);/*画图函数*/

voidstep(stack*s,pos*cur,stack*result)/*搜索可通路径函数*/

{if(stackempty(result)||s->t-s->bt-result->b){

for(cur->dir++;cur->dir<5;cur->dir++){/*探索"上下左右"四个方向是否可通*/

switch(cur->dir){case1:

/*向上*/

if(!

mg[cur->y-1][cur->x]){

mg[cur->y][cur->x]=1;

push(s,cur);

cur->y--;

cur->dir=0;

return;}

break;

case2:

/*向右*/

if(!

mg[cur->y][cur->x+1]){

mg[cur->y][cur->x]=1;

push(s,cur);

cur->x++;

cur->dir=0;

return;}

break;/*向下*/

case3:

if(!

mg[cur->y+1][cur->x]){

mg[cur->y][cur->x]=1;

push(s,cur);

cur->y++;

cur->dir=0;

return;}

break;

case4:

/*向左*/

if(!

mg[cur->y][cur->x-1]){

mg[cur->y][cur->x]=1;

push(s,cur);

cur->x--;

cur->dir=0;

return;}

break;

default:

exit(0);}

}

}

setfillstyle(SOLID_FILL,2);/*可走路径设置为绿色*/

draw(cur->y,cur->x);/*画出可走路径*/

pop(s,cur);

mg[cur->y][cur->x]=0;}/*从栈s中弹出探索路径坐标*/

voidsavepath(stack*s,pos*cur,stack*result)/*保存最短路径函数*/

{pos*top=s->t;

if(stackempty(result)){/*若栈result为空*/

push(result,cur);/*可通路径坐标存入result栈中*/

while(top>s->b)

push(result,--top);}

/*若result栈中元素多于s栈中元素则清空reslut栈并把可通路径坐标

存入result栈中*/

elseif(result->t-result->b>s->t-s->b){

clearstack(result);

push(result,cur);

while(top>s->b)

push(result,--top);}}

voiddraw(inty,intx)

{bar(130+15*x,130+15*y,117+15*x,117+15*y);/*绘制方块大小*/}

voidmain(void)/*主函数*/

{intx,y;

intgd=DETECT,gm;

charch;

stack*s=NULL;/*初始化栈s,result和路径坐标指针cur*/

stack*result=NULL;

pos*cur=NULL;

EXEC:

printf("Pleaseinputthesizeofmaze(n*n):

");/*输入迷宫大小*/

scanf("%d",&n);

if(n>24)/*屏幕所显示的最大迷宫*/

{printf("\nThenumberissolarge!

Tryitagain!

\n");

gotoEXEC;}

for(i=0;i

{mg[i][0]=1;

mg[i][n-1]=1;

mg[0][i]=1;

mg[n-1][i]=1;}

for(j=1;j

for(r=1;r

mg[j][r]=rand()%2;

initgraph(&gd,&gm,"");/*在屏幕上绘画出迷宫*/

for(x=0;x

for(y=0;y

if(mg[y][x]){

setfillstyle(SOLID_FILL,9);/*墙设置为蓝色*/

draw(y,x);/*在屏幕上画出墙*/}}

result=(stack*)malloc(sizeof(stack));/*由系统生成result,s栈*/

initstack(result);

s=(stack*)malloc(sizeof(stack));

cur=(pos*)malloc(sizeof(pos));

up:

printf("Pleaseinputthestartpath(c,d):

");/*输入起点*/

scanf("%d%d",&d,&c);

printf("Pleaseinputtheendpath(a,b):

");/*输入终点*/

scanf("%d%d",&b,&a);

if(c>n-2||d>n-2||a>n-2||b>n-2||c==0||d==0||a==0||b==0)/*判断是否为合法输入*/

{printf("Thenumberextendtheboundaryofthearray!

tryitagain!

\n");

gotoup;}

initstack(s);

cur->x=c;/*搜索起始坐标为(m,n)*/

cur->y=d;

cur->dir=0;

push(s,cur);/*把入口坐标压入栈s中*/

n=i=0;

do{if(cur->x==a&&cur->y==b)/*若找到出口则把s栈中元素存入result栈中*/

savepath(s,cur,result);

step(s,cur,result);

}while(!

stackempty(s));/*当s栈非空时*/

if(stackempty(result))/*若result栈为空*/

{printf("nowayavailable!

");}/*没有找到路径*/

else{intch=0;

printf("followingistheshortestpath:

\n");/*以下是最短路径*/

while(!

stackempty(result)){/*若栈非空*/

pop(result,cur);/*从result栈中弹出数据*/

setfillstyle(SOLID_FILL,15);/*路径为白色*/

draw(cur->y,cur->x);/*在屏幕上画出路径*/

if(ch>8){putchar('\n');ch=0;}/*一行打印八个坐标*/

printf("(%d,%d),",cur->x,cur->y);/*在屏幕上输出路径坐标*/

ch++;n++;i++;

dongx[i]=cur->x;dongy[i]=cur->y;/*把路径坐标存入数组dongx[]和dongy[]中*/

}

/*产生动画*/

for(i=1;i<=n;i++)

{x1=138+15*(dongx[i]-1);

y1=138+15*(dongy[i]-1);

setcolor(4);/*4表示红色*/

line(x1-5,y1,x1+5,y1);/*绘制红色十字*/

line(x1,y1-5,x1,y1+5);

for(z=0;z<9e+6;z++);/*时间延迟*/

/*擦除所走过的路径*/

setcolor(15);/*15表示白色*/

line(x1-5,y1,x1+5,y1);

line(x1,y1-5,x1,y1+5);}

}

for(i=0;i<23;i++)

printf("\n");

printf("\nDoyouwantacontinue(Y/N)?

\n");/*是否继续生成迷宫*/

destroystack(s);/*销毁栈s*/

destroystack(result);/*销毁栈result*/

free(cur);

ch=getch();

if(ch=='y'||ch=='Y')

gotoEXEC;}/*返回程序起始址*/

 

参考文献

1严蔚敏,吴伟民.《数据结构(C语言版)》.清华大学出版社.

2严蔚敏,吴伟民.《数据结构题集(C语言版)》.清华大学出版社.

3《DATASTRUCTUREWITHC++》.WilliamFord,WilliamTcpp.清华大学出版社(影印版).

4谭浩强.《C语言程序设计》.清华大学出版社.

 

总结

在这三周的数据结构课程设计中,我的题目是:

迷宫问题,这三周课程设计中,通过该题目的设计过程,我加深了对栈的逻辑结构,存储结构及入栈出栈过程的理解,对栈的基本运算的实现有所掌握,对课本中所学的各种数据结构进一步理解和掌握,学会了如何把学到的知识用于解决实际问题,锻炼了自己动手的能力。

一个人要完成所有的工作是非常困难和耗时的。

在以后的学习中我会更加注意各个方面的能力的协调发展。

在课程设计时遇到了很多的问题,在老师的帮助,和对各种资料的查阅中,将问题解决,培养了我自主动手,独立研究的能力,为今后在学习工作中能更好的发展打下了坚实的基础。

三周的课程设计很短暂,但其间的内容是很充实的,在其中我学习到了很多平时书本中无法学到的东西,积累了经验,锻炼了自己分析问题,解决问题的能力,并学会了如何将所学的各课知识融会,组织,来配合学习,三周中我收益很大,学到很多。

 

致谢

首先感谢我的指导老师李睿老师,他在我的课程设计过程中提出了指导性的方案和架构,并指引我阅读相关的资料和书籍,使我在不熟悉的领域中仍能迅速掌握新的技术。

感谢我的数据结构老师李睿老师和C语言老师任旭鹏在以往的基础课学习中为我打下良好的基础,这是我这次课程设计能够顺利完成的前提。

我的同学在设计完成后对程序的测试,没有他们,也许就难以发现一些潜在的错误,在此一并表示感谢。

 

附件Ⅰ部分源程序代码

//直接插入排序算法

#include

#include

#defineNULL0

#defineLENsizeof(structstudent)

structstudent/*定义节点*/

{

intnum;

intscore;

structstudent*next;

};

/*建立链表*/

structstudent*creat(void)

{

structstudent*head,*p1,*p2;

intn=0;

p1=p2=(structstudent*)malloc(LEN);

scanf("%d,%d",&p1->num,&p1->score);

while(p1->num!

=0)

{

n=n+1;

if(n==1)head->next=p1;

elsep2->next=p1;

p2=p1;

p1=(structstudent*)malloc(LEN);

scanf("%d,%d",&p1->num,&p1->score);

}

p2->next=NULL;

returnhead;

}

/*打印单链表信息*/

print(structstudent*head)

{

structstudent*p=creat();

if(p!

=NULL)

{

for(;p!

=NULL;p=p->next){

printf("%d,%d\n",p->num,p->score);

}

}

}

/*插入排序*/

structstudent*insert_sort(structstudent*head)

{

structstudent*h1,*p,*q,*t;

head=creat();

h1=head->next;

while(h1!

=NULL)/*循环直至等待插入的链表为空*/

{

t=h1;/*保存等待插入链表的头指针*/

h1=h1->next;//h1后移

p=head;

q=head;

while(p!

=NULL&&t->num>p->num)/*进行节点大小比较*/

{

q=p;

p=p->next;

}

if(p==q)/*说明待排序点值最大,应排在首位*/

{

head=t;

t->next=p;

}

else{

t->next=p;

q->next=t;

}

}

returnhead;

}

/*主函数*/

main()

{

structstudent*head,*p;

printf("PleaseInputInfo(endwith0,0):

\n");

head=insert_sort(&head);

printf("Sort:

\n");

for(p=head;p!

=NULL;p=p->next)

printf("%d:

%d\n",p->num,p->score);

getch();

}

 

运行结果:

 

源程序(带注释)

#include

#include

#include

#include

typedefstruct{/*定义结构体其中坐标(x,y)搜索方向dir*/

intx,y;

intdir;

}pos,elem;

typedefstruct{/*定义栈顶指针t栈底指针b栈的大小size*/

elem*b,*t;

intsize;

}stack;

voidinitstack(stack*s)/*定义栈的存储空间*/

{s->b=(elem*)malloc(150*sizeof(elem));

if(s->b){

s->t=

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工程科技

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2