日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

你必须会的DFS的递归实现与堆栈实现

發布時間:2025/6/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 你必须会的DFS的递归实现与堆栈实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 一. 算法原理
      • 1.堆棧式實現方法
      • 2.遞歸式實現方法
    • 二.具體實現
      • 1.實例
      • 2.結果
    • 三.如何輸出所有的路徑?

一. 算法原理

相比于BFS利用隊列實現中心擴散式搜索
DFS就是利用堆棧的思想(先進后出),利用回溯算法,或者使用dfs遞歸,直觀上看是一條路走到黑,如果找到南墻,便回到上個路口,繼續一條路走到黑…如此往復,直到到達目標,所以稱之為深度優先搜索。

1.堆棧式實現方法

  • 首先將根節點壓入堆棧中。
  • 從堆棧中pop一個節點,并檢驗它是否為目標。
    • 如果找到目標,則結束搜索并回傳結果。
    • 否則將它所有尚未檢驗過的直接子節點加入堆棧中。
  • 若堆棧為空,表示整張圖都檢查過了——亦即圖中沒有所搜索的目標。結束搜索并回傳“找不到目標”。
  • 重復步驟2。

偽代碼

stack.push(root) while(!stack.isEmpty())node = stack.pop()for each neighbor node的相鄰節點if neighbor未被訪問stack.push(neightbor)//記錄路徑stack.parent = node//其余操作...todo...

2.遞歸式實現方法

  • 給定根節點
  • 遍歷根節點所有未被訪問的相鄰節點
    • 如果找到目標,則結束搜索并傳回結果
    • 否則將該相鄰節點設置為新的根節點,重復步驟2
    • 若沒有未被訪問的相鄰節點,則結束本分支的搜索并返回
  • 所有分支都遍歷完畢,結束搜索并回傳“找不到目標”。

偽代碼:

DFS()dfsVisit(root)dfsVisit(node)for each neighbor node的相鄰節點if neighbor沒有訪問過//記錄路徑neighbor.parent = root//其他操作todo..dfs(neighbor)

二.具體實現

選用常見的遞歸實現

package com.example.DFS;import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;public class DFS {// <1, [2, 3]>表示節點1的父節點是節點2,到源點距離為3private Map<Integer, int[]> disTo;/*** @param edges 一個節點到其他節點的距離* [[0, 1, 1], [1, 2, 2]] 表示點0到點1的距離為1,點1到點2的距離為2* @param n 所有節點個數 1<= n <= 1000* @param k 源節點 1< k <n*/public Map<Integer, int[]> DFS(int[][] edges, int n, int k){//通過edges數組生成有向圖//<0, <{1,2}, {2,3}>>表示節點0有1,2兩個相鄰節點,距離分別為2, 3Map<Integer, List<int[]>> graph = new HashMap<>();for(int[] edge:edges){if(!graph.containsKey(edge[0]))graph.put(edge[0], new ArrayList<int[]>());graph.get(edge[0]).add(new int[]{edge[1], edge[2]});}//初始化disTodisTo = new HashMap<>();for(int i=0; i<n; i++){if(i==k)disTo.put(i, new int[]{k, 0});else disTo.put(i, new int[]{-1, Integer.MAX_VALUE});}dfsVisit(graph, k);return disTo;}/*** dfs* @param graph* @param k*/private void dfsVisit(Map<Integer, List<int[]>> graph, int k){if(graph.containsKey(k))for(int[] edge:graph.get(k)){int[] temp = disTo.get(edge[0]);//保證該節點未被訪問if(temp[0] == -1 && temp[1] == Integer.MAX_VALUE) {//setParent 記錄路徑temp[0] = k;//setDisTo 記錄距離temp[1] = disTo.get(k)[1] + edge[1];//遞歸實現dfsVisit(graph, edge[0]);}}}/*** 輸出結果* @param disTo* @param end*/public void printPath(Map<Integer, int[]> disTo,int pathTo){int distance = disTo.get(pathTo)[1];List<Integer> path = new ArrayList<>();int temp = pathTo;path.add(temp);while (temp!=0 && temp!=-1){temp = disTo.get(temp)[0];path.add(temp);}System.out.print("從初始節點到節點"+end+"的距離為"+distance+"\n"+"路徑為:\n"+path.get(0));for(int i=1;i<path.size();i++){System.out.print("<--"+path.get(i));}} }

1.實例

測試輸入
輸入:

edges:n:k:pathTo:
{{0, 1, 15},{0, 3, 5},604
{1, 5, 6}, {3, 5, 20},
{1, 2, 15}, {3, 2, 30},
{2, 4, 10}, {5, 4, 9}};

預計輸出:距離:30 路徑:0–>1–>5–>4

環境:windows10,java11

2.結果

試著輸出到節點5的路徑和距離

三.如何輸出所有的路徑?

在一個圖沒有環的情況下,或者先去環后,允許一個節點可以由多個不同的父節點向下遍歷到,這樣可以找到圖中真正的所有路徑


你可能還敢興趣的圖論算法(均附Java實現代碼):

  • 算法實驗–主函數只有五行的Floyed的算法以及最短路徑輸出

  • 你必須會的–Dijkstra算法–單源最短路徑問題

  • 你了解歐拉回路嗎?

  • 你必須會的啟發式搜索算法–A*算法

總結

以上是生活随笔為你收集整理的你必须会的DFS的递归实现与堆栈实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。