zoukankan      html  css  js  c++  java
  • 深度优先搜索和广度优先搜索(转)

    转自:http://blog.csdn.net/andyelvis/article/details/1728378
      有两种常用的方法可用来搜索图:即深度优先搜索和广度优先搜索。它们最终都会到达所有连通的顶点。深度优先搜索通过栈来实现,而广度优先搜索通过队列来实现。  
      深度优先搜索:
      下面图中的数字显示了深度优先搜索顶点被访问的顺序。

      为了实现深度优先搜索,首先选择一个起始顶点并需要遵守三个规则:
      (1) 如果可能,访问一个邻接的未访问顶点,标记它,并把它放入栈中。
      (2) 当不能执行规则1时,如果栈不空,就从栈中弹出一个顶点。
      (3) 如果不能执行规则1和规则2,就完成了整个搜索过程。

      广度优先搜索:
      在深度优先搜索中,算法表现得好像要尽快地远离起始点似的。相反,在广度优先搜索中,算法好像要尽可能地靠近起始点。它首先访问起始顶点的所有邻接点,然后再访问较远的区域。它是用队列来实现的。
      下面图中的数字显示了广度优先搜索顶点被访问的顺序。

      实现广度优先搜索,也要遵守三个规则:
      (1) 访问下一个未来访问的邻接点,这个顶点必须是当前顶点的邻接点,标记它,并把它插入到队列中。
      (2) 如果因为已经没有未访问顶点而不能执行规则1时,那么从队列头取一个顶点,并使其成为当前顶点。
      (3) 如果因为队列为空而不能执行规则2,则搜索结束。

    下面是一个图类的java代码,dfs()为深度优先搜索算法,bfs()为广度优先搜索算法:
    //用于实现深度优先搜索的栈类
      1 class StackX{ 
      2     private final int SIZE=20;
      3     private int[] st;
      4     private int top;
      5     public StackX(){
      6         st=new int[SIZE];
      7         top=-1;
      8     }
      9     public void push(int j){
     10         st[++top]=j;
     11     }
     12     public int pop(){
     13         return st[top--];
     14     }
     15     public int peek(){
     16         return st[top];
     17     }
     18     public boolean isEmpty(){
     19         return top==-1;
     20     }
     21 }
     22 //用于实现广度优先搜索的队列类
     23 class Queue{
     24     private final int SIZE=20;
     25     private int[] queArray;
     26     private int front;  //父节点
     27     private int rear;  //子节点
     28     public Queue(){
     29         queArray=new int[SIZE];
     30         front=0;
     31         rear=-1;
     32     }
     33     public void insert(int j){  //扩展此父节点的儿子
     34         if(rear==SIZE-1)
     35             rear=-1;
     36         queArray[++rear]=j;
     37     }
     38     public int remove(){   //换下一个父节点
     39         int temp=queArray[front++];
     40         if(front==SIZE)
     41             front=0;
     42         return temp;
     43     }
     44     public boolean isEmpty(){
     45         return ((rear+1==front)||(front+SIZE-1==rear));
     46     }
     47 }
     48 //顶点类
     49 class Vertex{
     50     public char label;
     51     public boolean wasVisited;
     52     public Vertex(char lab){
     53         label=lab;
     54         wasVisited=false;
     55     }
     56 }
     57 //图类
     58 public class Graph {
     59     
     60     private final int MAX_VERTS=20;
     61     private Vertex vertexList[];
     62     private int adjMat[][];
     63     private int nVerts;
     64     private StackX theStack;
     65     private Queue theQueue;
     66     
     67     /** Creates a new instance of Graph */
     68     public Graph() {
     69         vertexList=new Vertex[MAX_VERTS];
     70         adjMat=new int[MAX_VERTS][MAX_VERTS];
     71         nVerts=0;
     72         for (int j = 0; j < MAX_VERTS; j++) {
     73             for (int k = 0; k < MAX_VERTS; k++) {
     74                 adjMat[j][k]=0;
     75             }
     76         }
     77         theStack=new StackX();
     78         theQueue=new Queue();
     79     }
     80     //增加一个顶点
     81     public void addVertex(char lab){
     82         vertexList[nVerts++]=new Vertex(lab);
     83     }
     84     //增加一条边
     85     public void addEdge(int start,int end){
     86         adjMat[start][end]=1;
     87         adjMat[end][start]=1;
     88     }
     89     public void displayVertex(int v){
     90         System.out.print(vertexList[v].label);
     91     }
     92     //深度优先搜索
     93     public void dfs(){
     94         vertexList[0].wasVisited=true;
     95         displayVertex(0);
     96         theStack.push(0);
     97         while(!theStack.isEmpty()){
     98             int v=getAdjUnvisitedVertex(theStack.peek());
     99             if(v==-1)
    100                 theStack.pop();
    101             else{
    102                 vertexList[v].wasVisited=true;
    103                 displayVertex(v);
    104                 theStack.push(v);
    105             }
    106         }
    107         for(int j=0;j<nVerts;j++)
    108             vertexList[j].wasVisited=false;
    109     }
    110     //得到与v顶点邻接且未访问过的顶点标号
    111     public int getAdjUnvisitedVertex(int v){
    112         for (int j = 0; j < nVerts; j++) {
    113             if(adjMat[v][j]==1&&vertexList[j].wasVisited==false)
    114                 return j;
    115         }
    116         return -1;
    117     }
    118     //广度优先搜索
    119     public void bfs(){
    120         vertexList[0].wasVisited=true;
    121         displayVertex(0);
    122         theQueue.insert(0);
    123         int v2;
    124         while(!theQueue.isEmpty()){
    125             int v1=theQueue.remove();
    126             while((v2=getAdjUnvisitedVertex(v1))!=-1){
    127                 vertexList[v2].wasVisited=true;
    128                 displayVertex(v2);
    129                 theQueue.insert(v2);
    130             }
    131         }
    132         for (int j = 0; j < nVerts; j++) {
    133             vertexList[j].wasVisited=false;
    134         }
    135     }
    136     
    137 }
  • 相关阅读:
    php method_exists( $object , string $method_name )
    php伪类型 (mixed)
    6.6-2-数组与数据结构(用数组及其函数实现堆栈等数据结构)
    6.6-1-php数组相关(2)
    2017.6.5-2-php数组相关(1)
    2017.6.5-1-php函数应用及流程控制
    CodePage
    bat批处理教程
    pip安装及源
    CentOS安装Python3
  • 原文地址:https://www.cnblogs.com/jslee/p/3446129.html
Copyright © 2011-2022 走看看