两种简单的搜索算法

搜索算法是图论中常用到的算法,这里介绍两种常用的算法。这两种算法都是是以队列为基础的。

最简单的搜索方法:迷宫搜索,这种搜索方法是从当前位置出发,向四周辐射,直到搜索到目标位置,这种搜索方法的特性是:每向前推进一步花费的步骤数(时间)是相同的,所以这种搜索方法的实现非常的简单,我们只需要将走过的地方标记,然后将符合条件的待搜索部分压入搜索队列即可。这里我们只需要普通队列即可。(队列的构造及使用方法)

下面我们以下面的一个搜索图为例,演示这种基本的搜索方法。

我们从start开始搜索,到end结束。其中青绿色方格不可通过,无颜色的方格可以通过,

其中每移动一个方格,需要花费一个单位时间,下面我们来计算该过程花费的时间。

1

2

3

4

5

6

7

8

9

10

11

start

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

end

下面我们用字符来模拟上面的图表。S代表startE代表endO代表无色方格,即可通过方格,N代表不可通过表格。

OOOOO

ONNNN

OSOON

OONON

OONON

OONON

OONOE

算法实现过程:用一个结构体来描述每个方格(搜索节点)的性质,即位置坐标和时间,同时建立结构体类型的一个搜索队列,把开始位置压入首先压入搜索队列并把该位置标记为‘N’,然后向四周搜索,把符合条件的元素载入搜索队列接着把载入队列的元素标记为‘N’(已经搜索过),直到搜索到目标元素位置为止。

CODE:

#include

#include

#include

using namespace std;

int x1,y1,x2,y2;//记录搜索起始位置的坐标

char map[7][5];//记录需要搜索的图

int dir[4][2]={1,0,-1,0,0,1,0,-1};//控制前后左右四个方向

struct node//结构体用来描述每一个压入队列中元素的性质

{

int x,y,time;//记录每个表格的位置和处于该表格时的时间

};

bool judge(int x,int y) //判断该表格处的元素是否能被搜索

{

if(x>=0&&x<7&&y>=0&&y<5&&map[x][y]!='N')

return true;

else

return false;

}


int BFS()

{

queueq;//声明以结构体为类型的队列q

node cur,next;//当前位置,下一个位置

int x,y,i;

cur.x=x1;cur.y=y1;cur.time=0;      //把开始位置处的方格首先载入方格

map[x1][y1]='N';

q.push(cur);

while(!q.empty())

{

cur=q.front();

q.pop();

if(cur.x==x2&&cur.y==y2)     //搜索到目标

return cur.time;

next.time=cur.time+1;

for(i=0;i<4;i++)             //当前位置下向四周搜索

{

next.x=x=cur.x+dir[i][0];

next.y=y=cur.y+dir[i][1];

if(judge(x,y))

{

q.push(next);

map[x][y]='N';

}

}

}

return -1;

}

int main()

{

int i,j;

for(i=0;i<7;i++)//读入搜索图

cin>>map[i];

for(i=0;i<7;i++)//得到搜索起始位置的坐标

for(j=0;j<5;j++)

{

if(map[i][j]=='S')

{x1=i;y1=j;}

if(map[i][j]=='E')

{x2=i;y2=j;}

}

int ans;

ans=BFS();

cout<


 

通过这个例子我们可以了解到这种搜索方法好像是地毯式的搜索,在搜索域内所有可搜索的元素(距离不超过起始位置的距离)都可以得到一个时间的记录。在上面代码的基础上稍作改动即可得到这张结果表。

下面来介绍 一种稍微复杂的搜索方法,上面的搜索例子里,每次移动一次花费的时间是一样的,如果移动到不同的方向花费的时间不等该怎么办呢?这就要用到优先队列。仍以具体的实例的为例。

问题描述:

4 5

OONOO

SNNNE

OOOOO

NOOON

给你一个n*m的方格,其中S代表你的位置,E代表你要到达的位置,N代表一堵墙,通过N你需要花费一个单位时间清理墙,一个单位时间通过该位置(即共2个单位时间);O代表你可以花费一个单位时间通过,请输出到达该地的最少时间?

算法分析:

实现这个目标,我们只需以上面那个例子为基础处理每步移动时间的不同即可,这里我们使用优先搜索队列可以解决。(优先队列的构造方法及使用)

Code

 

#include

#include

#include

using namespace std;

char map[100][100];

int n,m;

int x1,y1,x2,y2;

int dir[4][2]={0,1,0,-1,1,0,-1,0};

struct node

{

friend bool operator <(node a,node b)

{

return a.timeq;

node cur,next;

cur.x=x1;cur.y=y1;cur.time=0;

q.push(cur);

map[x1][y1]='#';

while(!q.empty())

{

cur=q.top();

q.pop();

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

{

next.x=x=cur.x+dir[i][0];

next.y=y=cur.y+dir[i][1];

if(x>=0&&x=0&&y>n>>m)

{

for(i=0;i>map[i];

for(i=0;i


你可能感兴趣的:(Algorithm)