圖的深度優先和廣度優先遍曆

來源:互聯網
上載者:User

有兩種常用的方法可用來搜尋圖:即深度優先搜尋和廣度優先搜尋。它們最終都會到達所有連通的頂點。深度優先搜尋通過棧來實現,而廣度優先搜尋通過隊列來實現。  

深度優先搜尋:
下面圖中的數字顯示了深度優先搜尋頂點被訪問的順序。

為了實現深度優先搜尋,首先選擇一個起始頂點並需要遵守三個規則:
(1) 如果可能,訪問一個鄰接的未訪問頂點,標記它,並把它放入棧中。
(2) 當不能執行規則1時,如果棧不空,就從棧中彈出一個頂點。
(3) 如果不能執行規則1和規則2,就完成了整個搜尋過程。

廣度優先搜尋:
在深度優先搜尋中,演算法表現得好像要儘快地遠離起始點似的。相反,在廣度優先搜尋中,演算法好像要儘可能地靠近起始點。它首先訪問起始頂點的所有鄰接點,然後再訪問較遠的地區。它是用隊列來實現的。
下面圖中的數字顯示了廣度優先搜尋頂點被訪問的順序。

實現廣度優先搜尋,也要遵守三個規則:
(1) 訪問下一個未來訪問的鄰接點,這個頂點必須是當前頂點的鄰接點,標記它,並把它插入到隊列中。
(2) 如果因為已經沒有未訪問頂點而不能執行規則1時,那麼從隊列頭取一個頂點,並使其成為當前頂點。
(3) 如果因為隊列為空白而不能執行規則2,則搜尋結束。

下面是一個圖類的java代碼,dfs()為深度優先搜尋演算法,bfs()為廣度優先搜尋演算法:
//用於實現深度優先搜尋的棧類
class StackX{
    private final int SIZE=20;
    private int[] st;
    private int top;
    public StackX(){
        st=new int[SIZE];
        top=-1;
    }
    public void push(int j){
        st[++top]=j;
    }
    public int pop(){
        return st[top--];
    }
    public int peek(){
        return st[top];
    }
    public boolean isEmpty(){
        return top==-1;
    }
}
//用於實現廣度優先搜尋的隊列類
class Queue{
    private final int SIZE=20;
    private int[] queArray;
    private int front;
    private int rear;
    public Queue(){
        queArray=new int[SIZE];
        front=0;
        rear=-1;
    }
    public void insert(int j){
        if(rear==SIZE-1)
            rear=-1;
        queArray[++rear]=j;
    }
    public int remove(){
        int temp=queArray[front++];
        if(front==SIZE)
            front=0;
        return temp;
    }
    public boolean isEmpty(){
        return ((rear+1==front)||(front+SIZE-1==rear));
    }
}
//頂點類
class Vertex{
    public char label;
    public boolean wasVisited;
    public Vertex(char lab){
        label=lab;
        wasVisited=false;
    }
}
//圖類
public class Graph {
    
    private final int MAX_VERTS=20;
    private Vertex vertexList[];
    private int adjMat[][];
    private int nVerts;
    private StackX theStack;
    private Queue theQueue;
    
    /** Creates a new instance of Graph */
    public Graph() {
        vertexList=new Vertex[MAX_VERTS];
        adjMat=new int[MAX_VERTS][MAX_VERTS];
        nVerts=0;
        for (int j = 0; j < MAX_VERTS; j++) {
            for (int k = 0; k < MAX_VERTS; k++) {
                adjMat[j][k]=0;
            }
        }
        theStack=new StackX();
        theQueue=new Queue();
    }
    //增加一個頂點
    public void addVertex(char lab){
        vertexList[nVerts++]=new Vertex(lab);
    }
    //增加一條邊
    public void addEdge(int start,int end){
        adjMat[start][end]=1;
        adjMat[end][start]=1;
    }
    public void displayVertex(int v){
        System.out.print(vertexList[v].label);
    }
    //深度優先搜尋
    public void dfs(){
        vertexList[0].wasVisited=true;
        displayVertex(0);
        theStack.push(0);
        while(!theStack.isEmpty()){
            int v=getAdjUnvisitedVertex(theStack.peek());
            if(v==-1)
                theStack.pop();
            else{
                vertexList[v].wasVisited=true;
                displayVertex(v);
                theStack.push(v);
            }
        }
        for(int j=0;j<nVerts;j++)
            vertexList[j].wasVisited=false;
    }
    //得到與v頂點鄰接且未訪問過的頂點標號
    public int getAdjUnvisitedVertex(int v){
        for (int j = 0; j < nVerts; j++) {
            if(adjMat[v][j]==1&&vertexList[j].wasVisited==false)
                return j;
        }
        return -1;
    }
    //廣度優先搜尋
    public void bfs(){
        vertexList[0].wasVisited=true;
        displayVertex(0);
        theQueue.insert(0);
        int v2;
        while(!theQueue.isEmpty()){
            int v1=theQueue.remove();
            while((v2=getAdjUnvisitedVertex(v1))!=-1){
                vertexList[v2].wasVisited=true;
                displayVertex(v2);
                theQueue.insert(v2);
            }
        }
        for (int j = 0; j < nVerts; j++) {
            vertexList[j].wasVisited=false;
        }
    }
    
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.