深度优先搜索学习五例之三(JAVA)

一、深度优先搜索框架一递归实现,流程如下:  
    public  void dfs(int v) {   
      visited[v] = true;  //访问起点v 
      System.out.print(v+"  ");   
      for (int i = 0; i < k; i++) {   
        //递归调用搜索没有被访问过的当前节点的下一个节点(邻接点)   
    if (G[v][i] == 1 && !visited[i])//G[v][i]是图的邻接矩阵   
          dfs(i);//递归调用   
      }   
    }   

 
例:八皇后问题是一个古老而著名的问题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

    高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。
 
  public class Queen{
   private int n = 8;
   private int a[]; //皇后放在 ( i, a[i] )
   private boolean visited[]; //如果visited[i]为true,表示第i列已经被占了.
   int total = 0; //方案总数

   public Queen(){
    a=new int[8];
    visited =new boolean[8];
   }


   public static void main(String args[]){
     Queen m=new Queen();
     m.dfs(0);
     System.out.println(m.getTotal());
    }


    private boolean can(int d){ //判断第d行的Queen可否放在第a[d]列
      if( visited[a[d]] )
       return false; //已经被占,则返回false
    for(int i=0; i<d; i++)
     if( Math.abs(a[d]-a[i])== Math.abs(i-d) )//如果第i行和第d行的Queen在同一对角线上,则返回false
          return false;
     return true;
    }

   private void output(){
     int i;
     total++;
     System.out.print("No" +total +":  ");
     for(i=0; i<n; i++)
        System.out.print(a[i]+1 +" ");
     System.out.println();
    }

    public int getTotal(){
     return total;
   }

   private void dfs(int d){
     if( d>=n ){ //找到一个解并输出
        output();
        return;
     }
     for(int i=0; i<n; i++){ //每一行均有n种放法
        a[d] = i; //第d行的Queen放在第i列
        if(can(d)){
          visited[i] = true;
          dfs(d+1); //如果第d行的方法可行,就放下一行
          visited[i] = false;//恢复现场
        }
      }
   }
}

 


运行:
D:\java>java   Queen
No1:  1 5 8 6 3 7 2 4
No2:  1 6 8 3 7 4 2 5
No3:  1 7 4 6 8 2 5 3
No4:  1 7 5 8 2 4 6 3
No5:  2 4 6 8 3 1 7 5
No6:  2 5 7 1 3 8 6 4
No7:  2 5 7 4 1 8 6 3
..........................
92

二、深度优先搜索框架二(栈实现)流程如下:
深度优先搜索学习五例之三(JAVA)

例:深度优先搜索之迷宫问题

import java.util.Stack;
////////////////////////////////////////////////
//深度优先搜索之迷宫问题
public class MazeDsf{
  private static final int M=9;
  private static final int N=8;
  
 //迷宫矩阵,0为通道,1为障碍
  //入口(0,0),出口(8,7)
   private int[][] Matrix = {
            { 0, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 0, 0, 0, 0, 0, 0, 0 },   
            { 0, 1, 1, 1, 1, 0, 1, 0 },    
            { 0, 0, 0, 0, 0, 0, 1, 0 },   
            { 0, 1, 0, 0, 0, 0, 1, 0 },    
            { 0, 1, 0, 1, 1, 0, 1, 0 },   
            { 0, 1, 0, 0, 0, 0, 1, 1 },    
            { 0, 1, 0, 0, 1, 0, 0, 0 },   
            { 0, 1, 1, 1, 1, 1, 0, 0 } };  


    //标记数组,初始化为false
    boolean visited[][];

    public MazeDsf(){
       visited=new boolean[M][N];
       
    }

   //节点
   class  Node{
     int x;
     int y;
     Node(int i,int j){
       x = i;
       y = j;
    }
  }


/*坐标系统
0
----------------->y
|
|
|
|
|
V
x
*/


  //右下上左
  private int x_off[] = {0,1,-1,0};
  private int y_off[] = {1,0,0,-1};

 //输出状态
 private void PrintVisited(){
   
   for(int i = 0; i < M; ++i){
     for(int j = 0; j < N; ++j)
       System.out.print(visited[i][j]+"     ");
    System.out.println();
  }
}

   //输出迷宫
 private void PrintMatrix(){
    System.out.println("入口(0,0),出口(8,7)的迷宫,0为通道,1为障碍:");
   for(int i = 0; i < M; ++i){
     for(int j = 0; j < N; ++j)
       System.out.print(Matrix[i][j]);
    System.out.println();
  }
}
  //输出一条路径
  //由于入栈路径是正序,要倒过来输出才是从入口到出口的路劲
  private void PrintPath(Stack<Node> s){
    System.out.println("一条迷宫路径:");
    Stack<Node> t=new Stack<Node>();
    while(!s.empty()){
      t.push(s.pop());
      
    }
    while(!t.empty()){
     System.out.print("("+t.peek().x+","+t.peek().y+")->");
     t.pop();
    }
    
    System.out.println();
}

 //深度优先搜索一条可能的路径
  private void DFS(){

  //1.初始化栈
  Stack<Node> s=new Stack<Node>();
  Node start=new Node(0,0);
  s.push(start);
  visited[0][0] = true;
  while(!s.empty()){
    
   //2.取得栈顶元素(注意不从栈内删除)
   Node top = s.peek();
   //3.遍历栈顶元素的邻节点
  
   int i=0;
   for(i = 0; i<4; ++i){ //右下上左
      int nx = top.x + x_off[i];
      int ny = top.y + y_off[i];
      if(nx >= 0 && nx < M && ny>=0 && ny< N &&!visited[nx][ny] && Matrix[nx][ny] == 0){
  
         //4.把满足条件的元素标记为已处理,并压入栈内
         Node newNode=new Node(nx,ny);
         visited[nx][ny] = true;
         s.push(newNode);
         //找到出口,终止搜索
         if(nx == 8 && ny == 7){
           //输出找到的路径
           PrintPath(s); 
           return;
        }
        break;
      }
   }
   //5.当前节点没有满足条件的邻节点,把当前栈顶元素删除
   if(i == 4){
     s.pop();
   }
 }
}



  //测试代码主函数
  public static void main(String args[]) { 
     MazeDsf maze=new MazeDsf();
     maze.PrintMatrix();
     maze.DFS();
   }
}

运行:
D:\java>java   MazeDsf
入口(0,0),出口(8,7)的迷宫,0为通道,1为障碍:
01111111
00000000
01111010
00000010
01000010
01011010
01000011
01001000
01111100
一条迷宫路径:
(0,0)->(1,0)->(1,1)->(1,2)->(1,3)->(1,4)->(1,5)->(2,5)->(3,5)->(4,5)->(5,5)->(6,
5)->(7,5)->(7,6)->(7,7)->(8,7)

你可能感兴趣的:(java,数据结构,编程,算法)