Java數據結構與算法之DFS


深度優先搜索算法

  1. 深度優先遍歷,從初始訪問結點出發,初始訪問結點可能有多個鄰接結點,深度優先遍歷的策略就是首先訪問第一個鄰接結點,然后再以這個被訪問的鄰接結點作為初始結點,訪問它的第一個鄰接結點,可以這樣理解:每次都在訪問完當前結點后首先訪問當前結點的第一個鄰接結點。
  2. 我們可以看到,這樣的訪問策略是優先往縱向挖掘深入,而不是對一個結點的所有鄰接結點進行橫向訪問。
  3. 顯然,深度優先搜索是一個遞歸的過程。

算法分析:

  1. 假設起始節點為1;先搜索1節點的右側鄰接節點為2,此時將1節點置為已搜索狀態;判斷2節點是否為已搜索狀態,若未搜索,則將2節點置為已搜索狀態;每次都優先搜索判斷右側鄰接節點;
  2. 如圖所示,若此時已搜索至5節點,發現右側鄰接節點為2且已處於已搜索狀態故遞歸至上一個節點8搜索左側鄰接節點處...層層遞歸判斷至1節點(在圖中沒有並表明遞歸路徑)
  3. 此時搜索判斷1節點的左側鄰接節點3不為已搜索狀態,故繼續進行先右側后左側鄰接節點搜索判斷操作;
  4. 直至最后一個節點6搜索判斷3節點為已搜索狀態,故遞歸至最初的1節點;判斷結束,搜索結束

代碼實現:

// 對dfs進行一個重載,遍歷我們所有的結點,並進行dfs
    public List<Integer> DFS() {
        isSreachs = new boolean[vertexList.size()];
        dfsArrays = new ArrayList<>();
        for (int i = 0; i < vertexList.size(); i++) {
            // 遍歷所有的結點,進行dfs[回溯]
            if (!isSreachs[i]) {
                dfsArrays = DFS(isSreachs[i], i);
            }
        }
        return dfsArrays;
    }

    public List<Integer> DFS(boolean isSreach, int i) {
    	// 首先我們將該節點添加進數組
        dfsArrays.add(showVertexList(i));
        // 將節點設置為已經訪問
        isSreachs[i] = true;
        // 查找節點i的第一個鄰接節點w
        int w = getFirstNeighbor(i);
        while (w != -1) { // 說明存在w
            if (!isSreachs[w]) {
                DFS(isSreachs[w],w);
            }
            // w節點已經被訪問過
            w = getNextNeightbor(i,w);
        }
        return dfsArrays;
    }

    // 得到第一個鄰接結點的下標
    public int getFirstNeighbor(int index) {
        for (int j = 0; j < vertexList.size(); j++) {
            if (edges[index][j] == 1) {
                return j;
            }
        }
        return -1;
    }

    // 根據前一個鄰接結點的下標來獲取下一個鄰接結點
    public int getNextNeightbor(int v1, int v2) {
        for (int i = v2+1; i < vertexList.size(); i++) {
            if (edges[v1][i] == 1) {
                return i;
            }
        }
        return -1;
    }

實現結果:

這里的結果與分析的結果有所出入,這是因為分析中借用了樹的概念,在實現中需要左右子樹遞歸。而這里則運用了上一節圖中鄰接矩陣的概念,將邊用二維矩陣的形式表示出來,故搜索順序會有些出入。
但所用的思想是一致的:一條路走到黑,再回頭。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM