分享
 
 
 

数据结构:栈和队列-迷宫问题求解

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

//--------------------文件名:Maze.cpp------------------------

//----------------------By SunxySong-------------------------

//说明:本程序以迷宫问题进行演示,了解栈和链表的数据结构.

//运行过程:随机生成迷宫地图(由于未详细设计算法,故地图较简单),

// 并演示找到出口路径的过程.

////////////////////////////////////////////////////////////

//主要算法思想:

// 1.初始化迷宫,构造辅助运行栈和结果链表

// 2.从入口开始

// do

// {

// if (当前位置可通)

// {

// 当前位置入栈

// if (当前位置是出口)

// {

// 结束

// }

// else

// {

// 取得当前位置当前方向上的下一位置为当前位置

// 将新当前位置入栈

// }

// }

// else

// {

// 从栈中弹出栈顶元素为当前位置

// while(当前位置已无下一有效位置 && 栈不为空)

// {

// 将当前位置标记为无效

// 弹出栈顶元素为当前位置

// }

// if (当前位置还有下一有效位置时)

// {

// 当前位置方向调整

// 当前位置进栈

// 取得取得当前位置当前方向上的下一位置为当前位置

// }

// }

// }while(栈不为空时);

// 未找到出口

// 3.生成新地图

// 4.显示地图

//////////////////////////////////////////////////////////////

//源代码在VC6+WIN2000sp2下编译通过

#include "stdafx.h"

#include <windows.h>

#include <stdlib.h>

#include <iostream>

#include <string>

#include <list>

#include <stack>

#include <time.h>

using namespace std;

//class:MazePos-----------------------------------------

//迷宫通道块类型

class MazePos

{

public:

int wx,ly; //块的X,Y坐标

int path; //块的类型;0:空块,-1:墙壁,1:出口路径

bool pass; //是否曾经过(对墙壁无意义);false:没有,true:曾经过

bool operator==(const MazePos pos)

{

return (wx==pos.wx && ly==pos.ly );

};

MazePos operator=(const MazePos pos)

{

wx=pos.wx;

ly=pos.ly;

pass=pos.pass;

path=pos.path;

return *this;

};

};

//End:MazePos---------------------------------------

//class:SElemType-----------------------------------------

//辅助栈元素类型

class SElemType

{

public:

int ord; //迷宫通道块路径上的序号

MazePos seat; //通道块在迷宫中的位置坐标

int di; //从此通道块走向下一通道块的方向

//0:无效,1:东,2:南,3:西,4:北

bool operator==(const SElemType et)

{

return (seat==et.seat);

};

SElemType operator=(const SElemType et)

{

ord =et.ord ;

seat =et.seat ;

di =et.di ;

return (*this);

};

};

//End:SElemType--------------------------------------

//struct:MazeMap-------------------------------------

//由通道块组成的迷宫地图

#define MAPWIDTH 10

#define MAPHEIGHT 10

typedef struct MazeMap

{

//由通道块矩阵构成

MazePos mazemap[MAPWIDTH][MAPHEIGHT];

}MazeMap;

//End:MazeMap---------------------------------------

//struct::MazeWay----------------------------------------

//辅助出口路径链表元素类型

typedef struct MazeWay

{

int wx,ly;

}MazeWay;

//End:MazeWay--------------------------------------------

//Class:Maze----------------------------------------

//主体类,迷宫路径问题求解

class Maze

{

public:

Maze(int width=MAPWIDTH,int height=MAPHEIGHT); //生成迷宫地图

~Maze();

void DoMaze(); //找出出口路径并显示

private:

bool InitOK; //初始化成功标志

MazeMap map; //迷宫地图

MazePos start,end; //迷宫的入口和出口

bool FindPath(); //主要函数,寻找出口路径

list<MazeWay> mazeway; //存放出口路径的临时链表

void RandMap(); //随机生成迷宫地图函数

bool CreateMap(bool init); //在初始和找到出口路径后生成相应地图函数

bool pass(MazePos curpos); //当前路径通道块是否可通(即是不是未经过的空块)

MazePos NextPos(MazePos curpos,int di); //取得当前通道块当前方向上的下一个通道块

bool Invalide(SElemType e); //使当前通道块标记为不可通

void DisplayMaze(); //显示迷宫地图

};

Maze::Maze(int width,int height)

{

//

//随机生成迷宫地图

CreateMap(true);

//显示地图

DisplayMaze();

}

Maze::~Maze()

{

//Add codes here

}

bool Maze::FindPath ()

{

//

//寻找出口,并生成出口路径链表

if(InitOK)

{

//MazeStack mstack;

stack<SElemType,list<SElemType> > mstack;

MazePos curpos=start;

int curstep=1; //经过的步数

MazeWay mw; //出口路径块元素

unsigned mwsize=mazeway.size (); //为显示运行过程而设

do

{

if(pass(curpos))

{

//如果当前位置可通(即是未走过的空块)

//封装栈元素,将当前位置进栈

SElemType e;

e.ord =curstep;

e.seat =curpos;

e.di =1;

mstack.push (e);

//保存当前位置到出口路径链表

mw.wx =e.seat .wx ;

mw.ly =e.seat .ly ;

mazeway.push_back (mw);

//如果是出口,则结束

if(curpos==end)

return true;

//不然就将得到下一个通道块

curpos=NextPos(curpos,e.di );

curstep++;

}

else

{

//当前位置不可通,则在栈内找到下一个位置

if(!mstack.empty())

{

SElemType e;

e=mstack.top ();

mstack.pop ();

//调整出口路径链表

mazeway.pop_back ();

while((e.di==0 || e.di ==4) && !mstack.empty ())

{

Invalide(e); //标记刻通道块不能通过

e=mstack.top ();

mstack.pop (); //退回一步

//调整出口路径链表

mazeway.pop_back ();

}

if(mstack.empty ())

return false;

else if( e.di<5)

{

e.di++;

e.di=e.di%5;

mstack.push (e);

//保存当前位置到出口路径链表

mw.wx =e.seat .wx ;

mw.ly =e.seat .ly ;

mazeway.push_back (mw);

curpos=NextPos(e.seat ,e.di );

}

}

}

///*//显示运行过程

if(mwsize!=mazeway.size () )

{

CreateMap(false);

DisplayMaze();

mwsize=mazeway.size ();

Sleep(800); //要包含windows.h头文件

}

//*

}while(!mstack.empty ());

}

return false;

}

MazePos Maze::NextPos(MazePos curpos,int di)

{

//

MazePos pos;

switch(di)

{

case 1:

pos=map.mazemap [curpos.wx+1][curpos.ly ] ;

break;

case 2:

pos=map.mazemap [curpos.wx][curpos.ly+1 ] ;

break;

case 3:

pos=map.mazemap [curpos.wx-1][curpos.ly] ;

break;

case 4:

pos=map.mazemap [curpos.wx][curpos.ly-1] ;

break;

}

return pos;

}

bool Maze::pass(MazePos curpos)

{

//

//通过MazePos类型参数传递的信息检查MazeMap map;

if(curpos.wx <0 ||

curpos.wx >=MAPWIDTH ||

curpos.ly <0 ||

curpos.ly >=MAPHEIGHT)

return false;

return (map.mazemap [curpos.wx ][curpos.ly ].path ==0 &&

map.mazemap [curpos.wx ][curpos.ly ].pass ==false );

}

void Maze::DoMaze ()

{

//

if(!InitOK)

return;

if(FindPath())

{

CreateMap(false);

DisplayMaze();

}

else

{

cout<<endl<<"NO PATH!"<<endl;

}

}

void Maze::RandMap ()

{

//

//只能生成从左上到右下的迷宫地图

MazeWay curway; //随机生成的当前正处理的出口路径块(组成mw)

list<MazeWay> mw; //随机生成的出口路径(由curway组成)

list<MazeWay>::iterator iter; //容器适配器

curway.wx =0;

curway.ly =1;

mw.push_back (curway);

curway.wx ++;

mw.push_back (curway);

srand(time(0)); //取得当前时间作为随机数种子

while(curway.wx <MAPWIDTH-1 && curway.ly <MAPHEIGHT-1)

{

if(rand()%2==1)

{

//生成随机X坐标上的路径块

curway.wx ++;

mw.push_back (curway);

}

else

{

//生成随机Y坐标上的路径块

curway.ly ++;

mw.push_back (curway);

}

}

srand(time(0));

for(int y=0;y<MAPHEIGHT;y++)

{

for(int x=0;x<MAPWIDTH;x++)

{

//填充每个通道块

map.mazemap [x][y].wx =x;

map.mazemap [x][y].ly =y;

map.mazemap [x][y].pass =false;

if(x==0||y==0||x==MAPWIDTH-1||y==MAPHEIGHT-1)

{

//生成四周墙壁

map.mazemap [x][y].path =-1;

//map.mazemap [x][y].pass =true;

}

else

{

if(rand()%10>=6) //数值越小,墙壁越多

{

map.mazemap [x][y].path =-1; //随机生成墙壁

//map.mazemap [x][y].pass =true;

}

else

{

map.mazemap [x][y].path =0; //生成空的通道块

//map.mazemap [x][y].pass =false;

}

}

}

}

//生成出口路径

for(iter=mw.begin ();iter!=mw.end ();iter++)

{

map.mazemap [(*iter).wx ][(*iter).ly ].path =0;

//map.mazemap [(*iter).wx ][(*iter).ly ].pass =false;

}

//生成入口和出口

start=map.mazemap [mw.front ().wx][mw.front ().ly];

end=map.mazemap [mw.back ().wx][mw.back ().ly];

//初始化成功

InitOK=true;

}

bool Maze::CreateMap (bool init)

{

//

if(init)

{

RandMap();

}

else

{

for(int y=0;y<MAPHEIGHT;y++)

for(int x=0;x<MAPWIDTH;x++)

{

if(map.mazemap [x][y].path ==0)

map.mazemap [x][y].pass =0;

}

list<MazeWay>::iterator iter;

for(iter=mazeway.begin ();iter!=mazeway.end ();iter++)

{

map.mazemap [(*iter).wx][(*iter).ly ].path =1;

}

}

return true;

}

bool Maze::Invalide (SElemType e)

{

//

//通过SElemType类型参数传递的信息修正MazeMap map;

if(e.seat .wx<0 ||

e.seat .wx>=MAPWIDTH ||

e.seat .ly<0 ||

e.seat .ly>=MAPHEIGHT)

return false;

map.mazemap [e.seat .wx][e.seat .ly ].pass =true;

return true;

}

void Maze::DisplayMaze ()

{

//

cout<<endl;

for(int y=0;y<MAPHEIGHT;y++)

{

for(int x=0;x<MAPWIDTH;x++)

{

switch (map.mazemap [x][y].path)

{

case -1:

cout<<"█";break; //墙壁图案

case 0:

cout<<" ";break; //空块图案

case 1:

cout<<"==";break; //出口路径图案

}

}

cout<<endl;

}

cout<<endl;

}

//End:Maze----------------------------------------

//main--------------------------------------------

//主函数,迷宫求解演示

int main(int argc, char* argv[])

{

//

cout<<"下面是随机生成的迷宫:"<<endl;

Maze mymaze; //生成迷宫

cout<<"按任意键演示迷宫解法!"<<endl;

system("pause");

mymaze.DoMaze (); //生成出口路径

cout<<"演示结束."<<endl;

system("pause");

return 0;

}

//End:main--------------------------------------------

下图为演示抓图

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有