<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
用回溯法链表求解迷宫问题,并加上完整的人物演示过程 (按一键小人开始搜索)
创建人: 颜清国 2006年3月18日(下载源码(点击右键,目标另存为))
说明: 程序中按照上-右-下-左搜索,运行效果如图
#include"graphics.h"#include"stdio.h"#include"dos.h"#define LENGTH sizeof(struct Node)/******************************************* 定义全局变量,用来保存PEOPLE的位置 *******************************************/struct site{ int mapsite; /*定义是墙还是可移动的*/ int xnow; int ynow;}psite[18][25];static int xp=1,yp=1,oldxp=1,oldyp=1;/*记录此时PAOPAO的位置和PAOPAO的个数*/typedef struct Node /*定义链表结点的结构体*/{ int x,y; int direction; struct Node*next;}node;/************************************栈的基本操作************************************/int findnext(node*head,node*p,int *direct);node*initstack(int x,int y,int direction);void push(node*head,node*p);void pop(node*head,node**p);void gettop(node*head,node*p);int stackempty(node*head);void dispstack(node*head);/****************************************** box()函数用来画出PAOPAO总的活动范围 *******************************************/void box(int x1,int y1,int x2,int y2){ line(x1,y1,x1,y2); line(x1,y1,x2,y1); line(x2,y1,x2,y2); line(x2,y2,x1,y2);}/******************************************* 函数用来在屏幕上画PEOPLE *******************************************/void drawpeople(int x,int y,int color){ int people[8]; people[0]=x-6; people[1]=y-4; people[2]=x-10; people[3]=y+10; people[4]=x+10; people[5]=y+10; people[6]=x+6; people[7]=y-4; setcolor(color); ellipse(x,y-7,0,360,10,4); drawpoly(4,people);}/******************************************* 函数用来移动PEOPLE在屏幕上的位置 *******************************************/void movepeople(){ if(psite[yp][xp].mapsite==0 ) { drawpeople(psite[yp][xp].xnow,psite[yp][xp].ynow,4); drawpeople(psite[oldyp][oldxp].xnow,psite[oldyp][oldxp].ynow,1); } }/******************************************* 函数用来初始化每个方格的属性和坐标, ** 其中属性来自外部的文件 *******************************************/void initsite(){ FILE*fp; int i=0,j=0; char ch; if((fp=fopen("site.txt","r"))==NULL) { printf("the site not found"); exit(1); } while((ch=fgetc(fp))!=EOF) { if(ch==10) continue; else { psite[i][j].mapsite=ch-48;/*读取数组,存入MAPSITE[]*/ if((j+1)>=25) i++; j=(j+1)%25; } } for(i=0;i<18;i=i++)/*初始化网格的中心坐标*/ { for(j=0;j<25;j++) { psite[i][j].ynow=12+24*i; psite[i][j].xnow=j*24+12; } } for(i=0;i<18;i=i++) { for(j=0;j<25;j++) { switch(psite[i][j].mapsite) { case 0:break; case 1: { setfillstyle(8,4); bar3d(psite[i][j].xnow-12,psite[i][j].ynow-12,psite[i][j].xnow+12, psite[i][j].ynow+12,0,1); floodfill(psite[i][j].xnow,psite[i][j].ynow,4); /*画出地图对应的东西,0是走道,1是墙,2是栅栏*/ break; } case 2: { setfillstyle(11,3); bar(psite[i][j].xnow-12,psite[i][j].ynow-12,psite[i][j].xnow+12, psite[i][j].ynow+12); floodfill(psite[i][j].xnow,psite[i][j].ynow,3); break; } default:printf("error");exit(1); } } }}void initall(){ int driver,mode; driver=DETECT; mode=0; registerbgidriver(EGAVGA_driver); initgraph(&driver,&mode,"\\tc"); clearviewport(); setbkcolor(1); box(0,0,600,432); box(1,1,599,431); initsite(); drawpeople(psite[yp][xp].xnow,psite[yp][xp].ynow,4); /*paopao的初始显示位置*/}/***************************************创建头结点,并初始化第一个结点*X,Y,DIRECTION为NODE结构体的域值****************************************/node*initstack(int x,int y,int direction){ node*head=(node*)malloc(LENGTH);/*创建头结点*/ node*p=(node*)malloc(LENGTH); p->x=x; /*初始化第一个结点*/ p->y=y; p->direction=direction; p->next=NULL; head->next=p; return head;}/*****************************************输出链表******************************************/void dispstack(node*head){ node*p=head->next; if(stackempty(head)) { printf("stack empty!"); return; } while(p->next!=NULL) { printf("(%d,%d) <---- ",p->x,p->y); p=p->next; } printf("(%d,%d)",p->x,p->y);}/******************************************判断栈是否为空,返回1时为空,为0是非空*******************************************/int stackempty(node*head){ return(head->next==NULL);}/**********************************************栈顶的元素出栈*注意这里的第二叁数要为node**p*否则其返回时P指针变量的值不被改变**********************************************/void pop(node*head,node**p){ if(stackempty(head)) { printf("stack empty!"); return; } else { (*p)=head->next; head->next=(*p)->next; (*p)->next=NULL; }}/**********************************************一元素入栈**********************************************/void push(node*head,node*p){ node*q=(node*)malloc(LENGTH); /*注意这里必须分配空间*/ if(stackempty(head)) { printf("stack empty!"); return; } else { q->x=p->x; /*简单的拷贝P里面的值域*/ q->y=p->y; q->direction=p->direction; q->next=head->next; head->next=q; }}/************************************************注意此处node*p指针变量的内容未变*但其指向的结构体单元的内容在返回后已经改变************************************************/void gettop(node*head,node*p){ p->x=head->next->x; p->y=head->next->y; p->direction=head->next->direction; /*注意此处不用p=head->next,防止指针域被复制而破坏链表*/}/**************************************************寻找下一个可以走的路径*找到返回1,否则返回0*其中direct是该可走点的方位**************************************************/int findnext(node*head,node*p,int *direct){ int d=head->next->direction,flag=0; int x=head->next->x,y=head->next->y; /*用来保存当前点的值,以便恢复*/ while((d < 5) && (flag==0)) { d++; p->x=x; /*每次换方位搜索还原该点值*/ p->y=y; switch(d) { case 1: p->y --; /*搜索上*/ break; case 2: p->x ++; /*搜索右*/ break; case 3: p->y ++; /*搜索下*/ break; case 4: p->x --; /*搜索左*/ break; } if(psite[p->y][p->x].mapsite==0) { flag=1; } } if(d==5) { return 0; /*没有找到*/ } else { (*direct)=d; /*记录若下次退栈时从该方位+1处开始搜索*/ p->direction=0;/*新的结点从上方位开始搜索*/ return 1; /*已找到下一路径*/ }}void delays(double second){ long far*ptr=(long far*)0x0040006c; long current,final; current=*ptr; final=current+second*1193180/65536; while(current<=final) current=*ptr;}int main(){ int direct=0; node*head,*p,*current=(node*)malloc(LENGTH); current->next=NULL; initall(); head=initstack(1,1,0);/*初始化头结点*/ while(!stackempty(head)) { gettop(head,current);/*取前一个或后一个结点*/ if((current->x == 23) && (current->y == 16))/*已经找到出口*/ { return 1; } else { if(findnext(head,current,&direct))/*搜索下一个,并且找到*/ { head->next->direction=direct;/*记录旧结点搜索到的方位*/ psite[head->next->y][head->next->x].mapsite=-1;/*标志已搜索过*/ push(head,current);/*当前结点入栈,其中方位号已置为上方*/ } else /*当前结点为死结点,不可走,退栈*/ { pop(head,¤t);/*回到了前一个结点*/ psite[head->next->y][head->next->x].mapsite=0;/*重新对上一结点搜索*/ } } oldxp=xp; oldyp=yp; xp=head->next->x; yp=head->next->y; movepeople(); delays(0.3); } }
分享到:
相关推荐
在IT领域,迷宫求解是一个经典的问题,它涉及到图论、算法设计和数据结构的运用。...以上就是“用群聚法求解迷宫问题”的核心内容,通过这个项目,开发者可以深入理解和实践数据结构、算法以及问题解决的技巧。
在这个场景中,我们关注的是使用Microsoft Foundation Classes (MFC)框架来实现一个迷宫求解器,特别地,是通过回溯法来解决这个问题。 **1. MFC简介** MFC是微软为Windows应用程序开发提供的一套C++类库,它封装了...
在头插法中,新元素被添加到链表头部,这使得栈顶元素始终是最先插入的元素,符合栈的后进先出(LIFO)特性。 在非递归的深度优先搜索(DFS)中,我们使用链式栈来模拟递归调用的过程。当遇到一个可通行的节点时,...
这个程序使用了递归和回溯法来解决迷宫问题,对于自动探索,它会尝试从当前位置向所有可能的方向移动,如果发现死胡同则回退到之前的位置,继续尝试其他方向,直到找到出口或者遍历完所有可能的路径。在手动探索模式...
在数据结构课程设计中,迷宫问题的求解是一个经典的实践课题,它涉及到深度优先搜索(DFS)、广度优先搜索(BFS)等算法。在这个项目中,我们使用C语言作为编程工具,并在VC++6.0开发环境中进行实现。 迷宫问题的基本...
在 Turbo C 中,回溯法的实现需要结合数组或链表来存储迷宫的状态,以及栈或递归调用来实现路径的回溯。 总的来说,"migong.zip"项目展示了如何在 Turbo C 环境下结合图形界面与回溯法来实现一个迷宫游戏。这不仅...
在计算机科学中,迷宫问题是一个经典的问题,它涉及到路径搜索和图遍历。本话题主要探讨如何使用C语言,结合队列和栈这两种数据结构,来实现迷宫的自动生成和求解。队列和栈是两种重要的数据结构,它们在算法设计中...
- **回溯法**:当DFS遇到死胡同时,通过撤销之前的决策(即反向操作)返回到未被探索的分支。 4. **最短路径算法**: - **Dijkstra算法**:适用于有权图,找到从起点到所有其他节点的最短路径。但原生的Dijkstra...
- **数据结构**:可能用到栈来处理括号运算,用数组或链表存储运算符和操作数。 - **算法**:解析输入的表达式,构建表达式树,然后进行前缀、中缀或后缀转换,最后进行运算。可以使用优先级队列处理运算符的...
在这个项目中,学生通常会被要求实现一个迷宫求解器,这将涵盖栈、队列、图和树等多种数据结构的应用。 **一、栈与深度优先搜索(DFS)** 栈是一种后进先出(LIFO)的数据结构,非常适合用于深度优先搜索。在迷宫问题...
综上所述,"数据结构课程设计迷宫求解"项目涵盖了数据结构的基本概念、搜索算法的运用以及问题解决策略的实践。通过这个项目,学生不仅能掌握数据结构的理论知识,还能提升编程和算法实现的能力。
典型的迷宫求解算法有回溯法(Backtracking)和A*搜索算法。回溯法是一种试错的方法,适用于所有路径都可逆的情况,而A*算法则结合了最佳优先搜索和启发式信息,能更高效地找到最短路径。VB代码中可能实现了其中的一...
【迷宫问题求解】迷宫问题是一种经典的计算机科学中的路径搜索问题,通常与数据结构和算法紧密相关。在这个课程设计中,学生被要求使用C或C++编程语言来实现迷宫问题的解决方案。迷宫被表示为一个m行n列的二维数组,...
【栈的链表实现】为了实现非递归的迷宫求解,我们使用栈作为主要的数据结构。栈是一种后进先出(LIFO)的数据结构,适合于回溯路径。我们可以创建一个链表形式的栈,其中每个节点包含一个位置坐标(i, j)和一个指向...
我们通常用数组或链表来表示迷宫,其中0表示可通行,1表示障碍。数据结构如栈和队列在此处发挥关键作用。 2. **深度优先搜索**(DFS):DFS是一种递归策略,从起点开始,沿着一条路径探索直到无法前进,然后回溯到...
2. **最短路径算法**:求解迷宫中最短路径的常见算法有宽度优先搜索(BFS)和Dijkstra算法。BFS通常用于找到两个节点间的最短路径,因为它保证了找到的第一个解就是最短的。Dijkstra算法则适用于加权图,但在这个...
这个项目旨在帮助学生深入理解如何使用不同的数据结构来解决实际问题,比如构建和求解迷宫。下面我们将详细讨论其中涉及的关键知识点。 1. **数据结构**: - **链表**:迷宫的路径可以被抽象为链表,每个节点代表...
这个过程需要考虑生成的迷宫是否具有解,可以通过回溯法或者预先设定规则来保证。 然后,是求解最短路径的部分。这里可以采用两种主要的搜索算法:深度优先搜索和广度优先搜索。DFS通常会找到一条路径,但不保证是...
创建迷宫通常有两种方法:随机生成和回溯法。随机生成方法会随机地在空的矩阵上放置障碍,然后通过某种规则(如确保起点和终点之间的连通性)调整迷宫。回溯法则从起点开始,逐步构造迷宫,每次尝试在一个空白位置...