宽度优先算法实践

  在下最近在看《编程之美》,由此来实践一些书中有趣的小例子,宽度优先算法便是其中之一。以下内容纯属个人见解,如有错误,请指出~

注:宽度优先算法是穷举方法的一种。

  在下面的实践中,我会用连连看游戏的核心算法(即搜索两个点的最短路径并连接起来),来进行讲述。

连连看是一个2D平面游戏,我使用一个二维数组来保存游戏数据

[

 [0,1,2,1],

 [0,0,0,1],

 [0,2,1,0],

 [0,2,0,0],

]

  这样子,可以看成一个连连看的模型了,0认为是空的,可以通过,非0值则是障碍物,不可通过。相同值可以连接在一块并进行消除。

 

  先讲大概原理:

  由于计算机逻辑本身是很笨的,它向前或者向后(进行 i++ 或者 i--)的操作;所以我们要引导它来达到我们想要的结果。

 

  假设我们选定了上述数组中的1(数组下标是list[0][1]的,下面称为A),查询A能连接查询的点,最终输出两个点的最短路径。

 

  首先我们开始对A进行遍历,也就是把另外一个节点取出来同A进行判断,如果节点的值为0,则跳过。值不为0且值不相同,则终止。值相等则认为该节点可以同A进行连接消除。

 

  进行一次向上遍历(由于A已经是在最上面了,条件不满足,退出执行)

  进行一次向右遍历(遍历第一个,由于节点值非空并且值不等于A,退出执行)

  进行一次向下遍历(遍历完毕,找到一个空值,没有找到相同值,同时将已经遍历过的节点,保存到一个map中)

  进行一次向左遍历(同上)

 

  至此,第一层遍历结束;把第一层遍历过并保存起来的节点取出来,再次进行上一步操作,进行第二层遍历,以此类推。

 

 

  你可以理解为是一颗从上到下的节点树,初始节点就是这颗树的根,通过每一层级遍历,去查询所有的能连接到的节点。

 

 

  在例子中,我设置的终止条件是遍历层级超过三次就退出执行。通过上面这个遍历,我们可以拿到A能连接到的所有节点,如果有遇到同一节点且路径不一致时,

例如:[

 [0,1,0,0],

 [0,0,0,0],

 [0,0,2,0],

 [0,0,1,0],

]

这个例子中,A能连接到另外一个1的值有两条路径(一个是向下,一个是向右然后再向下)。当遍历结束之后,去判断哪个值的搜索路径更短,进行保留即可。

 

下面是代码实现:

 

 

其他场景应用

写爬虫:例如写一个根据网站关注人去爬取关注人信息的爬虫(设定一个初始用户,查询该用户的全部关注人,获取关注人的信息,然后去获取关注人的关注人信息……),这个时候你就要判断该节点是不是已经搜索过了。

 

Ps:深度优先,只要你能理解宽度优先,也变相理解了深度优先。

 

第一次写博客,文笔不是很好,请多多指教~

posted @ 2017-05-14 15:10  最落  阅读(1309)  评论(0编辑  收藏  举报