深度优先搜索和广度优先搜索(转)

转自: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 }
原文地址:https://www.cnblogs.com/jslee/p/3446129.html