需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔《简单的循环队列》代码(版本有更新)。

进入今天的主题。

今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS)结合栈的示例应用。

一、队列和 BFS

众所周知,广度优先搜索(BFS)最为广泛使用场景是找出从根结点到目标结点的最短路径,而

结点的处理顺序与添加到队列的顺序是完全相同的顺序,即先进先出(FIFO)。

这就是我们在 BFS 中使用队列的原因。

二、栈和DFS

深度优先搜索(DFS),与 BFS 类似,也可用于查找从根结点到目标结点的路径。(请记住,是路径,但不是最短路径)

当我们到达最深的结点 时,我们需要回溯。当我们回溯时,我们将从栈中弹出最深结点,这实际上是推入到栈中的最后一个结点

结点的处理顺序是完全相反的顺序,就像是被添加到栈中一样,它是后进先出(LIFO)。这就是我们在 DFS 中使用栈的原因。

以上分别说明了使用在BFS中使用队列与在DFS中使用栈的原因,下面展示一示例说明其应用。

例:给定一个由 land(陆地)和 sea(海水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围

设计思路:通过BFS找出所有的land存入哈希表中,然后对其排序,最后通过DFS递归完成岛屿的统计。(其实本题不用这么复杂,直接递归即可,但为了阐述BFS和DFS,带此目的找了这个例题一起应用求解)。

测试用例为:

  1. iSea iSea iSea iSea iSea iSea iSea
  2. iSea Land iSea iSea Land iSea iSea
  3. iSea Land Land iSea iSea iSea iSea
  4. iSea iSea iSea Land iSea iSea iSea
  5. iSea Land iSea Land Land Land iSea
  6. iSea iSea iSea iSea iSea iSea iSea
  7. 岛屿的数量为:4

贴上源码(如只是阅读只看Main应该是可以理解):

1. IConnectable可连接器

  1. package com.chengcai.util;
  2. /**
  3.  * Created by chengcai on 2019/3/14.
  4.  */
  5. public interface IConnectable<T> {
  6.     Connector<T> connector();
  7. }
  1. package com.chengcai.util;
  2. /**
  3.  * Created by chengcai on 2019/3/14.
  4.  */
  5. public class Connector<T> {
  6.     public boolean isConnect=false;
  7.     public  Connector()
  8.     {
  9.           isConnect=true;
  10.     }
  11.     public boolean hasNext()
  12.     {
  13.         return isConnect;
  14.     }
  15. }
  1. package com.chengcai.util;
  2. /**
  3.  * Created by chengcai on 2019/3/18.
  4.  */
  5. public interface Ilivable {
  6. }
  1. 2.抽象地表对象AbstractEarthSurface
  1. package com.chengcai.util;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5.  * Created by chengcai on 2019/3/18.
  6.  */
  7. public abstract class AbstractEarthSurface {
  8.     public static int HashCode=1;
  9.     private int icon=0;
  10.     private AbstractEarthSurface right=null;
  11.     private AbstractEarthSurface down=null;
  12.     private AbstractEarthSurface left=null;
  13.     private AbstractEarthSurface up=null;
  14.     int row=0;
  15.     int col=0;
  16.     private String name;
  17.     private List<AbstractEarthSurface> list=new ArrayList<AbstractEarthSurface>();
  18.     public AbstractEarthSurface getRight()
  19.     {
  20.         return right;
  21.     }
  22.     public AbstractEarthSurface getDown()
  23.     {
  24.         return down;
  25.     }
  26.     public  AbstractEarthSurface getLeft(){return  left;}
  27.     public AbstractEarthSurface getUp(){return up;}
  28.     public  String getName()
  29.     {
  30.         return name;
  31.     }
  32.     public  int getIcon(){return icon;}
  33.     public  void setIcon(int s){
            icon=s;
  34.     }
  35.     public int getRow() {
  36.         return row;
  37.     }
  38.     public int getCol(){
  39.         return col;
  40.     }
  41.     public  void setRow(int r){
  42.         row=r;
  43.     }
  44.     public void setCol(int c){
  45.         col=c;
  46.     }
  47.     public void setRight(AbstractEarthSurface r)
  48.     {
  49.         if(r==null)
  50.             return;
  51.         list.add(r);
  52.         right=r;
  53.     }
  54.     public void setDown(AbstractEarthSurface d)
  55.     {
  56.         if (d==null)
  57.             return;
  58.         list.add(d);
  59.         down=d;
  60.     }
  61.     public void setLeft(AbstractEarthSurface l)
  62.     {
  63.         if(l==null)
  64.             return;
  65.         left=l;
  66.     }
  67.     public void setUp(AbstractEarthSurface u)
  68.     {
  69.         if(u==null)
  70.             return;
  71.         up=u;
  72.     }
  73.     public List<AbstractEarthSurface> getList()
  74.     {
  75.         return  list;
  76.     }
  77. }
  1. 3.定义统一对外操作对象Map,分别可操作sea,land,island对象
  1. package com.chengcai.util;
  2. import java.util.ArrayList;
  3. import java.util.Hashtable;
  4. import java.util.List;
  5. /**
  6.  * Created by chengcai on 2019/3/14.
  7.  */
  8. public class Map
  9. {
       private AbstractEarthSurface[][] map = null;
  10.    private island ild=null;
  11.     public Map() {
  12.     }
  13.     public AbstractEarthSurface getLand() {
  14.         return new Land();
  15.     }
  16.     public AbstractEarthSurface getSea() {
  17.         return  new Sea();
  18.     }
  19.     public island getIsland()
  20.     {
  21.         if (ild==null) {
  22.             ild= new island();
  23.         }
  24.         return  ild;
  25.     }
  26.     public void setMap(AbstractEarthSurface[][] imap)
  27.     {
  28.         map=imap;
  29.     }
  30.     public AbstractEarthSurface[][] getMap()
  31.     {
  32.         return this.map;
  33.     }
  34.     public class Land extends AbstractEarthSurface implements IConnectable
  35.     {
  36.         private int icon=1;
  37.         public Land()
  38.         {
  39.         }
  40.         public Connector connector()
  41.         {
  42.             return new Connector();
  43.         }
  44.         @Override
  45.         public  String getName()
  46.         {
  47.             return "Land";
  48.         }
  49.         @Override
  50.         public void setIcon(int s)
  51.         {
  52.             icon=s;
  53.         }
  54.         @Override
  55.         public int getIcon()
  56.         {
  57.             return  icon;
  58.         }
  59.     }
  60.     public class Sea extends AbstractEarthSurface
  61.     {
  62.         private   int icon=0;
  63.         public Sea()
  64.         {
  65.         }
  66.         @Override
  67.         public  String getName()
  68.         {
  69.             return "iSea";
  70.         }
  71.         @Override
  72.         public void setIcon(int s)
  73.         {
  74.             icon=s;
  75.         }
  76.         @Override
  77.         public int getIcon()
  78.         {
  79.             return  icon;
  80.         }
  81.     }
  82.     public class island implements Ilivable
  83.     {
  84.        
  85. Hashtable<Integer,AbstractEarthSurface> islandList=null;
  86.         Hashtable<String,AbstractEarthSurface> coordinate=null;
  87.         List<AbstractEarthSurface> tempList=null;
  88.         public island()
  89.         {
  90.             islandList=new Hashtable<Integer,AbstractEarthSurface>();
  91.             tempList=new ArrayList();
  92.         }
  93.         public  void addCoordinateHashTable(int r,int c,AbstractEarthSurface es)
  94.         {
  95.             if (coordinate==null)
  96.                 coordinate=new Hashtable<String,AbstractEarthSurface>();
  97.             this.coordinate.put(Integer.toString(r)+Integer.toString(c),es);
  98.         }
  99.         public AbstractEarthSurface getEarthSurface(int r, int c)
  100.         {
  101.             return  this.coordinate.get(Integer.toString(r)+Integer.toString(c));
  102.         }
  103.         public boolean isRowLastElement(String str,List<String> sls)       
  104. {
  105.             int index;
  106.             index=sls.indexOf(str)+1;
  107.             if(index>sls.size()-1)
  108.                 return true;
  109.             return this.coordinate.get(str).getRow()< this.coordinate.get(sls.get(index)).getRow();
  110.         }
  111.         public Hashtable<String,AbstractEarthSurface> getCoordinateHashtable()
  112.         {
  113.             if (coordinate==null)
  114.                 coordinate=new Hashtable<String,AbstractEarthSurface>();
  115.             return  this.coordinate;
  116.         }
  117.         public void Put(Integer hash, AbstractEarthSurface es)
  118.         {
  119.             if (!(es instanceof IConnectable))
  120.                 return;
  121.             this.islandList.put(hash,es);
  122.         }
  123.         public  void remove()
  124.         {
  125.             this.islandList.remove(this);
  126.         }
  127.         public Hashtable getIsland()
  128.         {
  129.             return  this.islandList;
  130.         }
  131.         public  void Add(AbstractEarthSurface es)
  132.         {
  133.             if (!(es instanceof IConnectable))
  134.                 return;
  135.             this.tempList.add(es);
  136.         }
  137.         public void ClearTemp()
  138.         {
  139.             if (tempList ==null )
  140.                 return;
  141.             this.tempList.clear();
  142.         }
  143.         public List<AbstractEarthSurface> getTempList()
  144.         {
  145.             return  this.tempList;
  146.         }
        }
  147. }
  1. 4.主函数
  1. package com.chengcai;
  2. import com.chengcai.util.*;
  3. import com.chengcai.util.Map;
  4. import java.util.*;
  5.  
  6.  
  7. public class Main {
  8.     //初始化测试用例
  9.     private static Map initMap()
  10.     {
  11.         Map map=new Map();
  12.         AbstractEarthSurface[]d1 ={map.getSea(),map.getSea(),map.getSea(),map.getSea(),
  13.                                     map.getSea(),map.getSea(),map.getSea()};
  14.         AbstractEarthSurface[]d2 ={map.getSea(),map.getLand(),map.getSea(),map.getSea(),map.getLand(),
  15.                                    map.getSea(),map.getSea()};
  16.         AbstractEarthSurface[]d3 ={map.getSea(),map.getLand(),map.getLand(),map.getSea(),
  17.                                    map.getSea(),map.getSea(),map.getSea()};
  18.         AbstractEarthSurface[]d4 ={map.getSea(),map.getSea(),map.getSea(),map.getLand(),
  19.                                    map.getSea(),map.getSea(),map.getSea()};
  20.         AbstractEarthSurface[]d5 ={map.getSea(),map.getLand(),map.getSea(),map.getLand(),
  21.                                    map.getLand(),map.getLand(),map.getSea()};
  22.         AbstractEarthSurface[]d6 ={map.getSea(),map.getSea(),map.getSea(),map.getSea(),
  23.                                    map.getSea(),map.getSea(),map.getSea()};
  24.         AbstractEarthSurface [][] data=new AbstractEarthSurface[6][7];
  25.         for (int i=0;i<6;i++)
  26.         {
  27.             for(int j=0;j<7;j++)
  28.             {
                    if (i==0) {
  29.                     data[i][j] = d1[j];
  30.                     data[i][j].setUp(null);
  31.                     if (j>0)
  32.                         data[i][j].setLeft(data[i][j-1]);
  33.                     if (j+1<7)
  34.                         data[i][j].setRight(d1[j+1]);
  35.                     data[i][j].setDown(d2[j]);
  36.                 }
  37.                 if (i==1) {
  38.                     data[i][j] = d2[j];
  39.                     data[i][j].setUp(data[i-1][j]);
  40.                     if (j>0)
  41.                         data[i][j].setLeft(data[i][j-1]);
  42.                     if (j+1<7)
  43.                         data[i][j].setRight(d2[j+1]);
  44.                     data[i][j].setDown(d3[j]);
  45.                 }
  46.                 if (i==2) {
  47.                     data[i][j] = d3[j];
  48.                     data[i][j].setUp(data[i-1][j]);
  49.                     if (j>0)
  50.                         data[i][j].setLeft(data[i][j-1]);
  51.                     if (j+1<7)
  52.                         data[i][j].setRight(d3[j+1]);
  53.                     data[i][j].setDown(d4[j]);
  54.                 }
  55.                 if (i==3) {
  56.                     data[i][j] = d4[j];
  57.                     data[i][j].setUp(data[i-1][j]);
  58.                     if (j>0)
  59.                         data[i][j].setLeft(data[i][j-1]);
  60.                     if (j+1<7)
  61.                         data[i][j].setRight(d4[j+1]);
  62.                     data[i][j].setDown(d5[j]);
  63.                 }
  64.                 if (i==4) {
  65.                     data[i][j] = d5[j];
  66.                     data[i][j].setUp(data[i-1][j]);
  67.                     if (j>0)
  68.                         data[i][j].setLeft(data[i][j-1]);
  69.                     if (j+1<7)
  70.                         data[i][j].setRight(d5[j+1]);
  71.                     data[i][j].setDown(d6[j]);
  72.                 }
  73.                 if (i==5) {
  74.                     data[i][j] = d6[j];
  75.                     data[i][j].setUp(data[i-1][j]);
  76.                     if (j>0)
  77.                         data[i][j].setLeft(data[i][j-1]);
  78.                     if (j+1<7)
  79.                         data[i][j].setRight(d6[j+1]);
  80.                     data[i][j].setDown(null);
  81.                 }
  82.                 data[i][j].setRow(i);
  83.                 data[i][j].setCol(j);
  84.             }
  85.         }
  86.         map.setMap(data);
  87.         return map;
  88.     }
  89.     private static int getIslandNumBFS(ICircleQueue q,Map map)
  90.     {
  91.         AbstractEarthSurface[][] data=map.getMap();
  92.         List<AbstractEarthSurface> cacheList=new ArrayList<AbstractEarthSurface>();
  93.         //用队列辅助实现广度优先查找所有Land
  94.         q.enQueue(data[0][0]);
  95.         while (!q.isEmpty())
  96.         {
  97.             int head=q.getQueueEntity().getHead();
  98.             AbstractEarthSurface queueFirstElement=(AbstractEarthSurface)q.getQueueEntity().getListCollection().get(head);
  99.             if (queueFirstElement instanceof IConnectable & !(map.getIsland().getCoordinateHashtable().containsValue(queueFirstElement))){
  100.                 map.getIsland().addCoordinateHashTable(queueFirstElement.getRow(),queueFirstElement.getCol(),queueFirstElement);
  101.             }
  102.             for (AbstractEarthSurface obj:queueFirstElement.getList()) {
  103.                 cacheList.add(obj);
  104.             }
  105.             Iterator<AbstractEarthSurface> it =cacheList.iterator();
  106.             while (it.hasNext())
  107.             {
  108.                 if (q.enQueue(it.next()))
  109.                     it.remove();
  110.             }
  111.             q.deQueue();
  112.         }
  113.         //对结果排序,便于AbstractEarthSurface.HashCode哈希值计算
  114.         Hashtable<String,AbstractEarthSurface> ht=map.getIsland().getCoordinateHashtable();
  115.         List<String> li=new ArrayList<String>(ht.keySet());
  116.         li.sort(new Comparator<String>() {           
    @Override
  117.             public int compare(String o1, String o2) {
  118.                 return o1.compareTo(o2);
  119.             }
  120.         });
  121.         for (String str:li) {
  122.             if (ht.get(str).getIcon()==1)
  123.             {
  124.                 AbstractEarthSurface.HashCode++;
  125.                 getIslandConnected(ht.get(str));
  126.                 map.getIsland().Put(AbstractEarthSurface.HashCode, ht.get(str)); 
  127.             }
  128.         }
  129.         return map.getIsland().getIsland().keySet().size();
  130.     }
  131.     //递归实现标识已访问的对象
  132.     private static void getIslandConnected(AbstractEarthSurface es)
  133.     {
  134.         if((es==null) || !(es instanceof IConnectable) || (es.getIcon()==3))
  135.             return;
  136.         es.setIcon(3);
  137.         getIslandConnected(es.getRight());
  138.         getIslandConnected(es.getLeft());
  139.         getIslandConnected(es.getUp());
  140.         getIslandConnected(es.getDown());
  141.     }
  142.     private  static void printResult(Map map,int IslandCount)
  143.     {
  144.         AbstractEarthSurface[][] printMap=map.getMap();
  145.         StringBuilder sb =new StringBuilder();
  146.         for(int i=0;i<printMap.length;i++)
  147.         {
  148.             for (int j=0;j<printMap[0].length;j++)
  149.             {
  150.                 sb.append(printMap[i][j].getName() +" ");
  151.                 if (j==printMap[0].length-1)
  152.                     sb.append("\n\r");
  153.             }
  154.         }
  155.         System.out.print("测试用例为:"+"\n\r");
  156.         System.out.print(sb.toString());
  157.         System.out.print("岛屿的数量为:"+ IslandCount +"\n\r");
  158.     }
  159.     public static void main(String[] args) {
  160.         Map map=null;
  161.         int islandNums=0;
  162.         ICircleQueue<AbstractEarthSurface> q=new CircleQueue<AbstractEarthSurface>();
  163.          map=initMap();
  164.         islandNums=getIslandNumBFS(q,map);
  165.         printResult(map,islandNums);
  166.     }
  167. }
  1. 5.运行结果:
  1. 测试用例为:
  2. iSea iSea iSea iSea iSea iSea iSea
  3. iSea Land iSea iSea Land iSea iSea
  4. iSea Land Land iSea iSea iSea iSea
  5. iSea iSea iSea Land iSea iSea iSea
  6. iSea Land iSea Land Land Land iSea
  7. iSea iSea iSea iSea iSea iSea iSea
  8. 岛屿的数量为:4
  1.  
  1.  

利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)的更多相关文章

  1. matlab练习程序(广度优先搜索BFS、深度优先搜索DFS)

    如此经典的算法竟一直没有单独的实现过,真是遗憾啊. 广度优先搜索在过去实现的二值图像连通区域标记和prim最小生成树算法时已经无意识的用到了,深度优先搜索倒是没用过. 这次单独的将两个算法实现出来,因 ...

  2. (转)广度优先搜索BFS和深度优先搜索DFS

    1. 广度优先搜索介绍 广度优先搜索算法(Breadth First Search),又称为"宽度优先搜索"或"横向优先搜索",简称BFS. 它的思想是:从图中 ...

  3. 广度优先遍历-BFS、深度优先遍历-DFS

    广度优先遍历-BFS 广度优先遍历类似与二叉树的层序遍历算法,它的基本思想是:首先访问起始顶点v,接着由v出发,依次访问v的各个未访问的顶点w1 w2 w3....wn,然后再依次访问w1 w2 w3 ...

  4. 广度优先算法(BFS)与深度优先算法(DFS)

    一.广度优先算法BFS(Breadth First Search) 基本实现思想 (1)顶点v入队列. (2)当队列非空时则继续执行,否则算法结束. (3)出队列取得队头顶点v: (4)查找顶点v的所 ...

  5. 数据结构和算法总结(一):广度优先搜索BFS和深度优先搜索DFS

    前言 这几天复习图论算法,觉得BFS和DFS挺重要的,而且应用比较多,故记录一下. 广度优先搜索 有一个有向图如图a 图a 广度优先搜索的策略是: 从起始点开始遍历其邻接的节点,由此向外不断扩散. 1 ...

  6. 广度优先搜索(BFS)与深度优先搜索(DFS)的对比及优缺点

    深搜,顾名思义,是深入其中.直取结果的一种搜索方法. 如果深搜是一个人,那么他的性格一定倔得像头牛!他从一点出发去旅游,只朝着一个方向走,除非路断了,他绝不改变方向!除非四个方向全都不通或遇到终点,他 ...

  7. 采用邻接矩阵表示图的深度优先搜索遍历(与深度优先搜索遍历连通图的递归算法仅仅是DFS的遍历方式变了)

    //采用邻接矩阵表示图的深度优先搜索遍历(与深度优先搜索遍历连通图的递归算法仅仅是DFS的遍历方式变了) #include <iostream> using namespace std; ...

  8. 广度优先(bfs)和深度优先搜索(dfs)的应用实例

    广度优先搜索应用举例:计算网络跳数 图结构在解决许多网络相关的问题时直到了重要的作用. 比如,用来确定在互联网中从一个结点到另一个结点(一个网络到其他网络的网关)的最佳路径.一种建模方法是采用无向图, ...

  9. 搜索与图论①-深度优先搜索(DFS)

    深度优先搜索(DFS) 例题一(指数型枚举) 把 1∼n 这 n 个整数排成一行后随机打乱顺序,输出所有可能的次序. 输入格式 一个整数 n. 输出格式 按照从小到大的顺序输出所有方案,每行 1 个. ...

随机推荐

  1. 2059 - Authentication plugin 'caching_sha2_password' cannot be loaded: dlopen(../Frameworks/caching_sha2_password.so, 2): image not found

    mac本地安装mysql后,navicat连接报错: - Authentication plugin ): image not found 解决方法 在控制台登陆后重新改下密码即可 ALTER USE ...

  2. UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)

  3. HDU - 3247 Resource Archiver (AC自动机,状压dp)

    \(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...

  4. 51nod1556 计算(默慈金数)

    Problem 有一个\(1*n\)的矩阵,固定第一个数为\(1\),其他填正整数, 且相邻数的差不能超过\(1\),求方案数. \(n\le 10^6\) Solution 容易发现答案是\(f_n ...

  5. ant 执行jmeter

    构建-invoke ant -properties jmeter.home=/home/userapp/apps/apache-jmeter-5.0report.title=kyh_register_ ...

  6. 新系统添加sshkey/pexpect基本使用

    Ansible密码认证 //配置Inventory [db] 10.10.10.12 10.10.10.162 [db:vars] #给db组下的主机设置变量 ansible_ssh_user=&qu ...

  7. Entity Framework系列教程汇总

    翻译自http://www.entityframeworktutorial.net/,使用EF几年时间了,一直没有系统总结过,所以翻译这一系统文章作为总结,由于英语功底有限,翻译的可能有些问题,欢迎指 ...

  8. Ubuntu屏幕分辨率无1920 1080

    xrandr 没有1920X1080分辨率,所以手动添加一个1080P分辨率,先输入“cvt 1920 1080”命令,查询一下1080P分辨率的有效扫描频率 然后 sudo xrandr --new ...

  9. MATLAB cftool工具数据拟合结果好坏判断

    SSE和RMSE比较小 拟合度R接近于1较好 * 统计参数模型的拟合优度 1.误差平方和(SSE) 2. R-Square(复相关系数或复测定系数) 3. Adjusted R-Square(调整自由 ...

  10. 解析中国天气网页面获取七日天气 (Java, Python)

    说明 解析中国天气网的页面,获取七日天气. 使用 htmlparser .这是它的 API 文档. 代码 SevenDayWeather.java import java.io.BufferedRea ...