C语言迷宫程序.docx
- 文档编号:27739855
- 上传时间:2023-07-04
- 格式:DOCX
- 页数:19
- 大小:217.91KB
C语言迷宫程序.docx
《C语言迷宫程序.docx》由会员分享,可在线阅读,更多相关《C语言迷宫程序.docx(19页珍藏版)》请在冰豆网上搜索。
C语言迷宫程序
基于栈的C语言迷宫问题与实现
问题描述
多年以来,迷宫冋题一直是令人感兴趣的题目。
实验心理学家训练老鼠在迷宫中寻找食物。
许多神秘主义小说家也曾经把英国乡村花园迷宫作为谋杀现场。
于是,老鼠过迷宫问题就此
产生,这是一个很有趣的计算机问题,主要利用“栈”是老鼠通过尝试的办法从入口穿过
迷宫走到出口。
迷宫只有两个门,一个叫做入口,另一个叫做出口。
把一只老鼠从一个无顶盖的大盒子的
入口处赶进迷宫。
迷宫中设置很多隔壁,对前进方向形成了多处障碍,在迷宫的唯一出口处
放置了一块奶酪,吸引老鼠在迷宫中寻找通路以到达出口。
求解迷宫问题,即找出从入口到
出口的路径。
—个迷宫可用上图所示方阵[m,n]表示,0表示能通过,1表示不能通过。
现假设耗子从左上角[1,1]进入迷宫,编写算法,寻求一条从右下角[m,n]出去的路径。
下图是一个迷宫的示意图:
算法基本思想
迷宫问题是栈应用的一个典型例子。
求解过程可采用回溯法。
回溯法是一种不断试探且及时纠正错误的搜索方法。
从入口出发,按某一方向向前探索,若能走通(未走过的),即
某处可以到达,则到达新点,否则试探下一方向;若所有的方向均没有通路,则沿原路返
回前一点,换下一个方向再继续试探,直到所有可能的通路都探索到,或找到一条通路,或
无路可走又返回到入口点。
在求解过程中,为了保证在到达某一点后不能向前继续行走(无路)时,能正确返回前一点以便继续从下一个方向向前试探,则需要用一个栈保存所能够到达的每一点的下标及从该点前进的方向,栈中保存的就是一条迷宫的通路。
为了确保程序能够终止,调整时,必须保证曾被放弃过的填数序列不被再次试验,即要求按某种有序模型生成填数序列。
给解的候选者设定一个被检验的顺序,按这个顺序逐一生成候选者并检验。
三.主要数据结构
1.方阵栈:
#defineSTACK_INI_SIZE100
typedefstruct
{
int*top;//指向栈的顶端域
int*base;//指向栈的低端域
intlength;//栈的长度
intstacksize;//栈的最大长度
}sqstack;
2.产生迷宫的矩阵二维数组
为了使每一个迷宫存在迷宫的边界和两个端口:
入口、出口,设置了一个二维数组,在迷宫的周边定义为1使得迷宫存在边界,并在(1,1),(x-2,y-2)初定义为0,即定义迷宫的出口,大大减小了无解的情况。
for(i=0;i for(j=0;j mg[i][j]=rand()%3;//产生随机数 i=0; for(j=0;j { mg[i][j]=1;//定义边界 mg[j][i]=1; } i=y-1; for(j=0;j mg[j][i]=1; i=x-1; for(j=0;j mg[i][j]=1; mg[1][1]=0;//定义出口和入口 mg[x-2][y-2]=0; 四.主要函数功能 1.voidinitstack(sqstack*s);/*初始化栈*/ 100的空间,将栈的原始长 将栈顶和栈底分别申请一段动态存储空间,将栈分配长度为度定义为2 2.voidstackpush(sqstack*s,int);/*增加栈顶*/ 将栈的动态存储空间增加50,将栈顶指针上移相应高度,特殊情况单独考虑见程序。 3.voidstackpop(sqstack*s);/*撤销栈顶*/栈空提示无法删除,其他情况删除栈顶。 4.voidstackinput(sqstack*s);/*输出栈*/ 输出寻找到的一条迷宫路径 5.intmgway(sqstack*s);/*迷宫路径*/寻找到可执行的一条迷宫路径 6.voiddestorystack(sqstack*s);/*撤销栈S*/ 将栈内元素清空 7.voidmakemg(sqstack*s);/*制造迷宫*/输入迷宫的长宽(2-15),并产生迷宫图 五.算例(生成演算结果) 本程序的运算环境为: codeblocks输入界面: 输入错误则重新输入 ■匸: Wse巧弹rvthonyX\Desla 谙输入迷宫的幺宽I长度范围2-茁,宜芭围空-丄前 黔龍宫的长宽(长度范围皿,宽范围-0曾窃聶显能ii过的迷宫需婪一段时间.请版心黑特,如玄渤后尢送显于岀迷宫样本请重试… 0->1i1 l_f183 2-^183 3->111 4^*11111 迷莒正确尼 l2^ 继续输入错误提示: 匙宫正确路径 CS1,01)(B1,02)(B2,S2>(02,93)C03,03〉还盘也续么丁竄入错误请重新输人 重新输入结果: 呼秒后无袪显示岀迷宫样本请畫试…・ 0->111111->10001 2->10109 3->10110 4->11103 5->1BQB1 6^100017F1003 8->101Q1 9->10000 10->11013 11->10000 12->101091111 医宫正确路径 11111111100901100100H1161011010^0011018^18101191006001103^0000180B1188S101611101100900000101»10000100900^101 B010611Q1111111111 <01,01><01,02><01,03><02.03><02,04X03,04X04,04> kR4,my <07,07X08,07><09,07X09,08><09^09><0? 10X0? 11? <10.11X10,12X11,12X12么? . 可以看到每个迷宫都存在“围墙” 六.分析算法 1.空间复杂度 固定空间需求: 25*25的二维迷宫数组可变空间需求: 初始化栈中申请了100倍int型所占空间大小的动态空间,加入栈顶时额外申请50倍int型所占空间大小 2.时间复杂度 可以通过“程序步”对程序的时间复杂度进行测量,可以引入count计数器进行测量,考虑到其复杂程度,本程序将不采用此方法。 本程序的排错率较高,计算机会改掉没有通路的栈,并随机生成有通路迷宫,提高了程序的执行效率,并给迷宫添加了必要的围墙和出口、入口有助于执行效率的提高。 但对于路径的搜索,栈并没有引入方向指针,在后面,通过flag进行标记来确定栈的路径的寻找的,一定程度上会影响执行效率。 附录: C语言源程序 #include #defineSTACK_INI_SIZE100 #defineSTACKINCREMENT50 #defineNULL0 typedefstruct { int*top; int*base; intlength; intstacksize; }sqstack; intmg[25][25]; intm=1,n=1,x,y;/*********************************************/main() { voidinitstack(sqstack*s);/*初始化栈*/voidstackpush(sqstack*s,int);/*增加栈顶*/voidstackpop(sqstack*s);/*撤销栈顶*/voidstackinput(sqstack*s);/*输出栈*/intmgway(sqstack*s);/*迷宫路径*/voiddestorystack(sqstack*s);/*撤销栈S*/voidmakemg(sqstack*s);/*制造迷宫*/sqstacks; inti,flag1=1,flag2=1,flag3=1; charch;srand((unsigned)time(NULL)); while(flag1) { initstack(&s); flag2=1; makemg(&s);i=mgway(&s); if(i==0) printf("此迷宫没有通路\n"); else stackinput(&s);destorystack(&s); printf("还继续么? "); fflush(stdin);scanf("%c",&ch); while(flag2) { if(ch=='n'||ch=='N') { flag1=0; flag2=0; } elseif(ch=='y'||ch=='Y') { flag1=1; flag2=0; } else { printf("输入错误请重新输入"); fflush(stdin); scanf("%c",&ch); } } } } /*********************************************/ voidinitstack(sqstack*s)/*初始化栈*/ { s->top=s->base=(int*)malloc(STACK_INI_SIZE*sizeof(int));if(! s->base) exit (1); s->stacksize=STACK_INI_SIZE; *(s->base)=0; s->top++; *(s->top)=101; s->top++; s->length=2; } /*********************************************/ voidstackpush(sqstack*s,inti)/*增加栈顶*/ {if(s->length>=s->stacksize) { printf("路过"); s->base=(int*)realloc(s->base,(STACK_INI_SIZE+STACKINCREMENT)*sizeof(int));if(! s->base) exit (1); s->top=s->base+s->length; s->stacksize+=STACKINCREMENT;stackinput(s); } if(s->length==0) { *(s->base)=i; s->top++; s->length++; } else { *(s->top)=i; s->top++; s->length++; } } /*********************************************/ voidstackpop(sqstack*s)/*删除栈顶*/ { if(s->length==0) printf("栈空无法删除"); if(s->length==1) { s->top--; *(s->top)=*(s->base)=NULL; s->length=0; } else { s->top--; *(s->top)=NULL; s->length--; } } /*********************************************/ voidstackinput(sqstack*s)/*迷宫栈的输出*/ { intw,x,y,z,i=0,*p;p=s->base; p++; printf("迷宫正确路径\n"); while(p! =s->top) {printf("(%d%d,%d%d)",x=*p/1000,y=*p/100%10,z=*p%100/10,w=*p%10); p++; i++; if(i==7) {printf("\n");i=0; } } } /*********************************************/ intmgway(sqstack*s)/*迷宫路径*/ { intgudge(sqstack*s,int);/*判断是否能通行*/inthoming(sqstack*s);/*退栈后I所对应的方向*/inti=1,j,k; while(s->top! =s->base) { if(i<5)j=gudge(s,i); if(j==1&&i<5) { k=m*100+n;stackpush(s,k); if(m==y-2&&n==x-2) {return (1); } elsei=1; } else { if(m==0&&n==0)return(0); elseif(i==4||i==5) {i=homing(s);stackpop(s);i++; } elsei++; } } return(0); } /*********************************************/ intgudge(sqstack*s,inti)/*退栈后i所对应的方向*/{ intecho(sqstack*s); if(i==1) n++; if(i==2) m++; if(i==3) n--; if(i==4) m--; if((mg[m][n]==0||mg[m][n]==2)&&echo(s))return (1); else { if(i==1) n--; if(i==2) m--; if(i==3) n++; if(i==4) m++; return(0); } } /*********************************************/ intecho(sqstack*s) { inti,*p,*q; i=m*100+n; p=s->top;q=s->base;q++; p--; while(p! =q&&*p! =i) p--; if(*p==i)return(0); else return (1); } /*********************************************/ inthoming(sqstack*s)/*i退位后所对应的方向*/ { inta,b,c,d,*q; q=s->top; q--; a=(*q)/100; b=(*q)%100; q--; c=(*q)/100; d=(*q)%100; m=(*q)/100; n=(*q)%100;if(a==c) { if(d-b==1) return(3); elseif(d-b==-1) return (1); } elseif(b==d) { if(c-a==1) return(4); elseif(c-a==-1) return (2); } return(0); } voiddestorystack(sqstack*s) {if(*(s->base)! =NULL)free(s->base); s->length=0; } /*********************************************/ voidmakemg(sqstack*s)/*创建迷宫及输出迷宫图的函数*/{ intmgway(sqstack*s); voidclearstack(sqstack*s); intflag=1,flag2=1,i,j,k; charch; while(flag) { printf("请输入迷宫的长宽(长度范围2-15,宽范围2-15)\n"); printf("输入长"); fflush(stdin); scanf("%d",&y); printf("输入宽"); fflush(stdin); scanf("%d",&x); if(x<16&&x>3&&y>3&&y<16) flag=0; if(flag==0) printf("自动筛选能通过的迷宫需要一段时间,请耐心等待,如20秒后无法显示出迷宫样本 请重试......\n"); } flag=1; while(flag2) { m=1; n=1; for(i=0;i for(j=0;j mg[i][j]=rand()%3; i=0; for(j=0;j { mg[i][j]=1; mg[j][i]=1; } i=y-1; for(j=0;j mg[j][i]=1; i=x-1; for(j=0;j mg[i][j]=1; mg[1][1]=0; mg[x-2][y-2]=0; k=mgway(s); if(k==1) flag2=0; else clearstack(s); } printf(""); for(i=0;i printf("%2d",i); printf("\n"); for(i=0;i printf("J”); printf("\n"); for(i=0;i { printf("%2d”,i); for(j=0;j { if(mg[i][j]==2) printf("0"); else printf("%d",mg[i][j]); } printf("\n"); } } /*********************************************/ voidclearstack(sqstack*s)/*清空栈对于此程序而言*/ { s->top=s->base; *(s->base)=0; s->top++; *(s->top)=101; s->top++; s->length=2; } [此文档可自行编辑修改,如有侵权请告知删除,感谢您的支持,我们会努力把内容做得更好]
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 迷宫 程序