最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java數(shù)據(jù)結(jié)構(gòu)之圖的兩種搜索算法詳解

 更新時間:2022年11月01日 09:07:40   作者:JAVA旭陽  
在很多情況下,我們需要遍歷圖,得到圖的一些性質(zhì)。有關(guān)圖的搜索,最經(jīng)典的算法有深度優(yōu)先搜索和廣度優(yōu)先搜索,接下來我們分別講解這兩種搜索算法,需要的可以參考一下

前言

在很多情況下,我們需要遍歷圖,得到圖的一些性質(zhì),例如,找出圖中與指定的頂點相連的所有頂點,或者判定某個頂點與指定頂點是否相通,是非常常見的需求。

有關(guān)圖的搜索,最經(jīng)典的算法有深度優(yōu)先搜索和廣度優(yōu)先搜索,接下來我們分別講解這兩種搜索算法。

學(xué)習(xí)本文前請先閱讀這篇文章 【數(shù)據(jù)結(jié)構(gòu)與算法】圖的基礎(chǔ)概念和數(shù)據(jù)模型。

深度優(yōu)先搜索算法

所謂的深度優(yōu)先搜索,指的是在搜索時,如果遇到一個結(jié)點既有子結(jié)點,又有兄弟結(jié)點,那么先找子結(jié)點,然后找兄弟結(jié)點。

如上圖所示:

由于邊是沒有方向的,所以,如果4和5頂點相連,那么4會出現(xiàn)在5的相鄰鏈表中,5也會出現(xiàn)在4的相鄰鏈表中。

為了不對頂點進行重復(fù)搜索,應(yīng)該要有相應(yīng)的標記來表示當(dāng)前頂點有沒有搜索過,可以使用一個布爾類型的數(shù)組boolean[V] marked,索引代表頂點,值代表當(dāng)前頂點是否已經(jīng)搜索,如果已經(jīng)搜索,標記為true,

如果沒有搜索,標記為false;

API設(shè)計

類名DepthFirstSearch
成員變量1.private boolean[] marked: 索引代表頂點,值表示當(dāng)前頂點是否已經(jīng)被搜索2.private int count:記錄有多少個頂點與s頂點相通
構(gòu)造方法DepthFirstSearch(Graph G,int s):構(gòu)造深度優(yōu)先搜索對象,使用深度優(yōu)先搜索找出G圖中s頂點的所有相通頂點
成員方法1.private void dfs(Graph G, int v):使用深度優(yōu)先搜索找出G圖中v頂點的所有相通頂點2.public boolean marked(int w):判斷w頂點與s頂點是否相通3.public int count():獲取與頂點s相通的所有頂點的總數(shù)

代碼實現(xiàn)

/**
 * 圖的深度優(yōu)先搜索算法
 *
 * @author alvin
 * @date 2022/10/31
 * @since 1.0
 **/
public class DepthFirstSearch {
    //索引代表頂點,值表示當(dāng)前頂點是否已經(jīng)被搜索
    private boolean[] marked;
    //記錄有多少個頂點與s頂點相通
    private int count;

    //構(gòu)造深度優(yōu)先搜索對象,使用深度優(yōu)先搜索找出G圖中s頂點的所有相鄰頂點
    public DepthFirstSearch(Graph G, int s) {
        //創(chuàng)建一個和圖的頂點數(shù)一樣大小的布爾數(shù)組
        marked = new boolean[G.V()];
        dfs(G, s);
    }

    //使用深度優(yōu)先搜索找出G圖中v頂點的所有相鄰頂點
    private void dfs(Graph G, int v) {
        //把當(dāng)前頂點標記為已搜索
        marked[v] = true;
        //遍歷v頂點的鄰接表,得到每一個頂點w
        for (Integer w : G.adj(v)) {
            //遍歷v頂點的鄰接表,得到每一個頂點w
            if (!marked[w]) {
                //如果當(dāng)前頂點w沒有被搜索過,則遞歸搜索與w頂點相通的其他頂點
                dfs(G, w);
            }
        }

        //相通的頂點數(shù)量+1
        count++;
    }

    //判斷w頂點與s頂點是否相通
    public boolean marked(int w) {
        return marked[w];
    }

    //獲取與頂點s相通的所有頂點的總數(shù)
    public int count() {
        return count;
    }
}

測試:

public class DepthFirstSearchTest {

    @Test
    public void test() {
        //準備Graph對象
        Graph G = new Graph(13);
        G.addEdge(0,5);
        G.addEdge(0,1);
        G.addEdge(0,2);
        G.addEdge(0,6);
        G.addEdge(5,3);
        G.addEdge(5,4);
        G.addEdge(3,4);
        G.addEdge(4,6);
        G.addEdge(7,8);
        G.addEdge(9,11);
        G.addEdge(9,10);
        G.addEdge(9,12);
        G.addEdge(11,12);

        //準備深度優(yōu)先搜索對象
        DepthFirstSearch search = new DepthFirstSearch(G, 0);
        //測試與某個頂點相通的頂點數(shù)量
        int count = search.count();
        System.out.println("與起點0相通的頂點的數(shù)量為:"+count);
        //測試某個頂點與起點是否相同
        boolean marked1 = search.marked(5);
        System.out.println("頂點5和頂點0是否相通:"+marked1);
        boolean marked2 = search.marked(7);
        System.out.println("頂點7和頂點0是否相通:"+marked2);
    }
}

廣度優(yōu)先搜素算法

所謂的廣度優(yōu)先搜索,指的是在搜索時,如果遇到一個結(jié)點既有子結(jié)點,又有兄弟結(jié)點,那么先找兄弟結(jié)點,然后找子結(jié)點。

  • 可以通過借助一個輔助隊列實現(xiàn),先將1加入到隊列中
  • 然后取出1,將1的相鄰頂點加入到隊列中
  • 依次遞歸,如下圖所示:

API設(shè)計

類名BreadthFirstSearch
成員變量1.private boolean[] marked: 索引代表頂點,值表示當(dāng)前頂點是否已經(jīng)被搜索2.private int count:記錄有多少個頂點與s頂點相通3.private Queue waitSearch: 用來存儲待搜索鄰接表的點
構(gòu)造方法BreadthFirstSearch(Graph G,int s):構(gòu)造廣度優(yōu)先搜索對象,使用廣度優(yōu)先搜索找出G圖中s頂點的所有相鄰頂點
成員方法1.private void bfs(Graph G, int v):使用廣度優(yōu)先搜索找出G圖中v頂點的所有相鄰頂點2.public boolean marked(int w):判斷w頂點與s頂點是否相通3.public int count():獲取與頂點s相通的所有頂點的總數(shù)

代碼實現(xiàn)

/**
 * 圖的廣度優(yōu)先搜索算法
 *
 * @author alvin
 * @date 2022/10/31
 * @since 1.0
 **/
public class BreadthFirstSearch {
    //索引代表頂點,值表示當(dāng)前頂點是否已經(jīng)被搜索
    private boolean[] marked;
    //記錄有多少個頂點與s頂點相通
    private int count;
    //用來存儲待搜索鄰接表的點
    private Queue<Integer> waitSearch;

    //構(gòu)造廣度優(yōu)先搜索對象,使用廣度優(yōu)先搜索找出G圖中s頂點的所有相鄰頂點
    public BreadthFirstSearch(Graph G, int s) {
        this.marked = new boolean[G.V()];
        this.count = 0;
        this.waitSearch = new ArrayDeque<>();

        bfs(G, s);
    }

    //使用廣度優(yōu)先搜索找出G圖中v頂點的所有相鄰頂點
    private void bfs(Graph G, int v) {
        //把當(dāng)前頂點v標識為已搜索
        marked[v] = true;
        //讓頂點v進入隊列,待搜索
        waitSearch.add(v);
        //通過循環(huán),如果隊列不為空,則從隊列中彈出一個待搜索的頂點進行搜索
        while (!waitSearch.isEmpty()) {
            //彈出一個待搜索的頂點
            Integer wait = waitSearch.poll();
            //遍歷wait頂點的鄰接表
            for (Integer w : G.adj(wait)) {
                if (!marked[w]) {
                    bfs(G, w);
                }
            }
        }
        //讓相通的頂點+1;
        count++;

    }

    //判斷w頂點與s頂點是否相通
    public boolean marked(int w) {
        return marked[w];
    }

    //獲取與頂點s相通的所有頂點的總數(shù)
    public int count() {
        return count;
    }
}

測試代碼:

public class BreadthFirstSearchTest {

    @Test
    public void test() {
        //準備Graph對象
        Graph G = new Graph(13);
        G.addEdge(0, 5);
        G.addEdge(0, 1);
        G.addEdge(0, 2);
        G.addEdge(0, 6);
        G.addEdge(5, 3);
        G.addEdge(5, 4);
        G.addEdge(3, 4);
        G.addEdge(4, 6);
        G.addEdge(7, 8);
        G.addEdge(9, 11);
        G.addEdge(9, 10);
        G.addEdge(9, 12);
        G.addEdge(11, 12);

        //準備廣度優(yōu)先搜索對象
        BreadthFirstSearch search = new BreadthFirstSearch(G, 0);
        //測試與某個頂點相通的頂點數(shù)量
        int count = search.count();
        System.out.println("與起點0相通的頂點的數(shù)量為:" + count);
        //測試某個頂點與起點是否相同
        boolean marked1 = search.marked(5);
        System.out.println("頂點5和頂點0是否相通:" + marked1);
        boolean marked2 = search.marked(7);
        System.out.println("頂點7和頂點0是否相通:" + marked2);
    }
}

案例應(yīng)用

某省調(diào)查城鎮(zhèn)交通狀況,得到現(xiàn)有城鎮(zhèn)道路統(tǒng)計表,表中列出了每條道路直接連通的城鎮(zhèn)。“暢通工程”的目標是使全省任何兩個城鎮(zhèn)間都可以實現(xiàn)交通(但不一定有直接的道路相連,只要互相間接通過道路可達即可)。目前的道路狀況,9號城市和10號城市是否相通?9號城市和8號城市是否相通?

測試數(shù)據(jù)格式如上圖所示,總共有20個城市,目前已經(jīng)修改好了7條道路,問9號城市和10號城市是否相通?9號城市和8號城市是否相通?

解題思路:

  • 創(chuàng)建一個圖Graph對象,表示城市;
  • 分別調(diào)用addEdge(0,1),addEdge(6,9),addEdge(3,8),addEdge(5,11),addEdge(2,12),addEdge(6,10),addEdge(4,8),表示已經(jīng)修建好的道路把對應(yīng)的城市連接起來;
  • 通過Graph對象和頂點9,構(gòu)建DepthFirstSearch對象或BreadthFirstSearch對象;
  • 調(diào)用搜索對象的marked(10)方法和marked(8)方法,即可得到9和城市與10號城市以及9號城市與8號城市是否相通。

代碼實現(xiàn):

public class TrafficProjectGraph {

    public static void main(String[] args) throws Exception{
        //城市數(shù)量
        int totalNumber =  20;
        Graph G = new Graph(totalNumber);
        //添加城市的交通路線
        G.addEdge(0,1);
        G.addEdge(6,9);
        G.addEdge(3,8);
        G.addEdge(5,11);
        G.addEdge(2,12);
        G.addEdge(6,10);
        G.addEdge(4,8);

        //構(gòu)建一個深度優(yōu)先搜索對象,起點設(shè)置為頂點9
        DepthFirstSearch search = new DepthFirstSearch(G, 9);

        //調(diào)用marked方法,判斷8頂點和10頂點是否與起點9相通
        System.out.println("頂點8和頂點9是否相通:"+search.marked(8));
        System.out.println("頂點10和頂點9是否相通:"+search.marked(10));

    }
}

結(jié)果:

以上就是Java數(shù)據(jù)結(jié)構(gòu)之圖的兩種搜索算法詳解的詳細內(nèi)容,更多關(guān)于Java圖搜索算法的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 如何使用spring ResponseEntity處理http響應(yīng)

    如何使用spring ResponseEntity處理http響應(yīng)

    這篇文章主要介紹了如何使用spring ResponseEntity處理http響應(yīng)的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java開發(fā)分布式服務(wù)框架Dubbo原理機制詳解

    java開發(fā)分布式服務(wù)框架Dubbo原理機制詳解

    這篇文章主要為大家介紹了java開發(fā)分布式服務(wù)框架Dubbo的原理機制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2021-11-11
  • Java 實現(xiàn)滑動時間窗口限流算法的代碼

    Java 實現(xiàn)滑動時間窗口限流算法的代碼

    這篇文章主要介紹了Java 實現(xiàn)滑動時間窗口限流算法的代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • 解決jar包rar壓縮后無法運行問題

    解決jar包rar壓縮后無法運行問題

    這篇文章主要介紹了解決jar包rar壓縮后無法運行問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 淺談Spring AOP中args()和argNames的含義

    淺談Spring AOP中args()和argNames的含義

    這篇文章主要介紹了Spring AOP中args()和argNames的含義,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Nacos注冊中心的部署與用法示例詳解

    Nacos注冊中心的部署與用法示例詳解

    注冊中心是微服務(wù)架構(gòu)中的紐帶,類似于“通訊錄”,它記錄了服務(wù)和服務(wù)地址的映射關(guān)系,本文通過示例代碼給大家介紹Nacos注冊中心的部署與用法,感興趣的朋友跟隨小編一起看看吧
    2022-02-02
  • 第三方網(wǎng)站微信登錄java代碼實現(xiàn)

    第三方網(wǎng)站微信登錄java代碼實現(xiàn)

    這篇文章主要為大家詳細介紹了第三方網(wǎng)站微信登錄的java代碼實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • java中List數(shù)組用逗號分隔開轉(zhuǎn)成字符串2種方法

    java中List數(shù)組用逗號分隔開轉(zhuǎn)成字符串2種方法

    在我們?nèi)粘i_發(fā)中,在前后端交互的時候會遇到多個id或其他字段存放到一個字段中,這時我們會遇到一個List(集合)---->String(單個字段),這篇文章主要給大家介紹了關(guān)于java中List數(shù)組用逗號分隔開轉(zhuǎn)成字符串的2種方法,需要的朋友可以參考下
    2023-10-10
  • SpringBoot中@ComponentScan注解過濾排除不加載某個類的3種方法

    SpringBoot中@ComponentScan注解過濾排除不加載某個類的3種方法

    這篇文章主要給大家介紹了關(guān)于SpringBoot中@ComponentScan注解過濾排除不加載某個類的3種方法,文中通過實例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用SpringBoot具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2023-07-07
  • Go Java算法重復(fù)的DNA序列詳解

    Go Java算法重復(fù)的DNA序列詳解

    這篇文章主要為大家介紹了Go Java算法之重復(fù)的DNA序列的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08

最新評論

许昌市| 许昌市| 华蓥市| 临漳县| 宜城市| 麟游县| 德格县| 洱源县| 云南省| 隆回县| 安化县| 巴南区| 宁化县| 稷山县| 西贡区| 尖扎县| 安顺市| 上林县| 桐乡市| 岐山县| 永德县| 榆树市| 晋宁县| 筠连县| 仁寿县| 沿河| 龙岩市| 玉树县| 年辖:市辖区| 赤峰市| 金坛市| 高淳县| 闵行区| 潜山县| 樟树市| 托里县| 锦屏县| 牙克石市| 德安县| 临颍县| 开远市|