`
sylinx_yqg
  • 浏览: 139856 次
  • 性别: Icon_minigender_1
  • 来自: 福建 漳州
社区版块
存档分类
最新评论

用回溯法链表求解迷宫问题

阅读更多
<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);         }            }


分享到:
评论

相关推荐

    数据结构、算法与应用:C++语言描述(原书第2版)第二部分

    第20章 回溯法 20.1 算法思想 20.2 应用 20.2.1 货箱装载 20.2.2 0/1背包问题 20.2.3 最大完备子图 20.2.4 旅行商问题 20.2.5 电路板排列 第21章 分支定界 21.1 算法思想 21.2 应用 21.2.1 货箱装载 21.2.2 0/1背包...

    C++语言描述(PDF合集)

    11.5.2 用最优匹配法求解箱子装载 问题 357 11.5.3 交叉分布 359 11.6 参考及推荐读物 363 第12章 图 365 12.1 基本概念 365 12.2 应用 366 12.3 特性 368 12.4 抽象数据类型Graph和Digraph 370 12.5 无向图和有向图...

    数据结构算法与应用(C++语言描述).rar

    11.5.2 用最优匹配法求解箱子装载 问题 357 11.5.3 交叉分布 359 11.6 参考及推荐读物 363 第12章 图 365 12.1 基本概念 365 12.2 应用 366 12.3 特性 368 12.4 抽象数据类型Graph和Digraph 370 12.5 无向图和有向图...

    数据结构C++描述

    11.5.2 用最优匹配法求解箱子装载 问题 357 11.5.3 交叉分布 359 11.6 参考及推荐读物 363 第12章 图 365 12.1 基本概念 365 12.2 应用 366 12.3 特性 368 12.4 抽象数据类型Graph和Digraph 370 12.5 无向图和有向图...

    数据结构 C++描述

    11.5.2 用最优匹配法求解箱子装载 问题 357 11.5.3 交叉分布 359 11.6 参考及推荐读物 363 第12章 图 365 12.1 基本概念 365 12.2 应用 366 12.3 特性 368 12.4 抽象数据类型Graph和Digraph 370 12.5 无向图和有向图...

    数据结构算法与应用-C__语言描述

    11.5.2 用最优匹配法求解箱子装载 问题 357 11.5.3 交叉分布 359 11.6 参考及推荐读物 363 第12章 图 365 12.1 基本概念 365 12.2 应用 366 12.3 特性 368 12.4 抽象数据类型Graph和Digraph 370 12.5 无向图和有向图...

    数据结构算法与应用-C++语言描述

    11.5.2 用最优匹配法求解箱子装载 问题 357 11.5.3 交叉分布 359 11.6 参考及推荐读物 363 第12章 图 365 12.1 基本概念 365 12.2 应用 366 12.3 特性 368 12.4 抽象数据类型Graph和Digraph 370 12.5 无向图和有向图...

    数据结构、算法与应用--C++语言描述

    11.5.2 用最优匹配法求解箱子装载 问题 357 11.5.3 交叉分布 359 11.6 参考及推荐读物 363 第12章 图 365 12.1 基本概念 365 12.2 应用 366 12.3 特性 368 12.4 抽象数据类型Graph和Digraph 370 12.5 无向图和有向图...

    数据结构(C语言描述)

    11.5.2 用最优匹配法求解箱子装载 问题 357 11.5.3 交叉分布 359 11.6 参考及推荐读物 363 第12章 图 365 12.1 基本概念 365 12.2 应用 366 12.3 特性 368 12.4 抽象数据类型Graph和Digraph 370 12.5 无向图和有向图...

    数据结构算法与应用-C C++语言描述

    10.5.2 用相邻匹配法求解箱子装载 问题 316 第11章 搜索树 319 11.1 二叉搜索树 320 11.1.1 基本概念 320 11.1.2 抽象数据类型BSTree和 IndexedBSTree 321 11.1.3 类BSTree 322 11.1.4 搜索 322 11.1.5 插入 323 ...

    数据结构算法与应用-C++语言描述.rar

    11.5.2 用最优匹配法求解箱子装载 问题 357 11.5.3 交叉分布 359 11.6 参考及推荐读物 363 第12章 图 365 12.1 基本概念 365 12.2 应用 366 12.3 特性 368 12.4 抽象数据类型Graph和Digraph 370 12.5 无向...

    数据结构与算法:C++描述

    10.5.2 用相邻匹配法求解箱子装载 问题 316 第11章 搜索树 319 11.1 二叉搜索树 320 11.1.1 基本概念 320 11.1.2 抽象数据类型BSTree和 IndexedBSTree 321 11.1.3 类BSTree 322 11.1.4 搜索 322 11.1.5 插入 323 ...

    数据结构算法与应用 很详细的,数据结构算法全集 这个是你想找的

    树的高度 347 11.4.5 B-树的搜索 348 11.4.6 B-树的插入 348 11.4.7 B-树的删除 350 11.4.8 节点结构 353 11.5 应用 354 11.5.1 直方图 354 11.5.2 用最优匹配法求解箱子装载 问题 357...

    严蔚敏:数据结构题集(C语言版)

    6.7 回溯法与树的遍历 6.8 树的计数 第7章 图 7.1 图的定义和术语 7.2 图的存储结构 7.2.1 数组表示法 7.2.2 邻接表 7.2.3 十字链表 7.2.4 邻接多重表 7.3 图的遍历 7.3.1 深度优先搜索 7.3.2 广度优先搜索 7.4 图...

    数据结构的电子书(chm版)

    6、7、0 回溯法与树的遍历 6、8、0 树的计数 7、0、0 图 7、1、0 图的定义和术语 7、2、0 图的存储结构 7、2、1 数组表示法 7、2、2 邻接表 7、2、3 十字链表 7、2、4 邻接多重表 7、3、0 图的遍历 7、3、1 深度...

    c语言数据结构

    6、7、0 回溯法与树的遍历 6、8、0 树的计数 7、0、0 图 7、1、0 图的定义和术语 7、2、0 图的存储结构 7、2、1 数组表示法 7、2、2 邻接表 7、2、3 十字链表 7、2、4 邻接多重表 7、3、0 图的遍历 7、3、1 深度...

Global site tag (gtag.js) - Google Analytics