亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

前言

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

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

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

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

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

如上圖所示:

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

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

如果沒(méi)有搜索,標(biāo)記為false;

API設(shè)計(jì)

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

代碼實(shí)現(xiàn)

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

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

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

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

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

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

測(cè)試:

public class DepthFirstSearchTest {

    @Test
    public void test() {
        //準(zhǔn)備Graph對(duì)象
        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);

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

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

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

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

API設(shè)計(jì)

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

代碼實(shí)現(xiàn)

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

    //構(gòu)造廣度優(yōu)先搜索對(duì)象,使用廣度優(yōu)先搜索找出G圖中s頂點(diǎn)的所有相鄰頂點(diǎn)
    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頂點(diǎn)的所有相鄰頂點(diǎn)
    private void bfs(Graph G, int v) {
        //把當(dāng)前頂點(diǎn)v標(biāo)識(shí)為已搜索
        marked[v] = true;
        //讓頂點(diǎn)v進(jìn)入隊(duì)列,待搜索
        waitSearch.add(v);
        //通過(guò)循環(huán),如果隊(duì)列不為空,則從隊(duì)列中彈出一個(gè)待搜索的頂點(diǎn)進(jìn)行搜索
        while (!waitSearch.isEmpty()) {
            //彈出一個(gè)待搜索的頂點(diǎn)
            Integer wait = waitSearch.poll();
            //遍歷wait頂點(diǎn)的鄰接表
            for (Integer w : G.adj(wait)) {
                if (!marked[w]) {
                    bfs(G, w);
                }
            }
        }
        //讓相通的頂點(diǎn)+1;
        count++;

    }

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

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

測(cè)試代碼:

public class BreadthFirstSearchTest {

    @Test
    public void test() {
        //準(zhǔn)備Graph對(duì)象
        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);

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

案例應(yīng)用

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

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

解題思路:

  • 創(chuàng)建一個(gè)圖Graph對(duì)象,表示城市;
  • 分別調(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)修建好的道路把對(duì)應(yīng)的城市連接起來(lái);
  • 通過(guò)Graph對(duì)象和頂點(diǎn)9,構(gòu)建DepthFirstSearch對(duì)象或BreadthFirstSearch對(duì)象;
  • 調(diào)用搜索對(duì)象的marked(10)方法和marked(8)方法,即可得到9和城市與10號(hào)城市以及9號(hào)城市與8號(hào)城市是否相通。

代碼實(shí)現(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)建一個(gè)深度優(yōu)先搜索對(duì)象,起點(diǎn)設(shè)置為頂點(diǎn)9
        DepthFirstSearch search = new DepthFirstSearch(G, 9);

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

    }
}

結(jié)果:

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

相關(guān)文章

  • httpclient staleConnectionCheckEnabled獲取連接流程解析

    httpclient staleConnectionCheckEnabled獲取連接流程解析

    這篇文章主要為大家介紹了httpclient staleConnectionCheckEnabled獲取連接流程示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • mybatis多數(shù)據(jù)源動(dòng)態(tài)切換的完整步驟

    mybatis多數(shù)據(jù)源動(dòng)態(tài)切換的完整步驟

    這篇文章主要給大家介紹了關(guān)于mybatis多數(shù)據(jù)源動(dòng)態(tài)切換的完整步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 解決Maven 項(xiàng)目報(bào)錯(cuò) java.httpservlet和synchronized使用方法

    解決Maven 項(xiàng)目報(bào)錯(cuò) java.httpservlet和synchronized使用方法

    下面小編就為大家?guī)?lái)一篇解決Maven 項(xiàng)目報(bào)錯(cuò) java.httpservlet和synchronized使用方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • Java中LinkedHashSet的實(shí)現(xiàn)原理詳解

    Java中LinkedHashSet的實(shí)現(xiàn)原理詳解

    這篇文章主要介紹了Java中LinkedHasSet的實(shí)現(xiàn)原理詳解,LinkedHashSet?是具有可預(yù)知迭代順序的?Set?接口的哈希表和鏈接列表實(shí)現(xiàn),此實(shí)現(xiàn)與HashSet?的不同之處在于,后者維護(hù)著一個(gè)運(yùn)行于所有條目的雙重鏈接列表,需要的朋友可以參考下
    2023-09-09
  • 解決SpringBoot返回結(jié)果如果為null或空值不顯示處理問(wèn)題

    解決SpringBoot返回結(jié)果如果為null或空值不顯示處理問(wèn)題

    這篇文章主要介紹了解決SpringBoot返回結(jié)果如果為null或空值不顯示處理問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java Stream中自定義Collector實(shí)現(xiàn)復(fù)雜數(shù)據(jù)收集的方法

    Java Stream中自定義Collector實(shí)現(xiàn)復(fù)雜數(shù)據(jù)收集的方法

    Java Stream API中的Collector接口是一個(gè)強(qiáng)大的工具,它允許我們自定義數(shù)據(jù)收集、轉(zhuǎn)換和聚合的過(guò)程,,本文介紹了Java Stream中自定義Collector實(shí)現(xiàn)復(fù)雜數(shù)據(jù)收集方法,需要的朋友可以參考下
    2024-08-08
  • Springboot mybais配置多數(shù)據(jù)源過(guò)程解析

    Springboot mybais配置多數(shù)據(jù)源過(guò)程解析

    這篇文章主要介紹了Springboot+mybais配置多數(shù)據(jù)源過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java項(xiàng)目Guava包?HashMultimap使用及注意事項(xiàng)

    Java項(xiàng)目Guava包?HashMultimap使用及注意事項(xiàng)

    guava基本上可以說(shuō)是java開(kāi)發(fā)項(xiàng)目中,大概率會(huì)引入的包,今天介紹的主角是一個(gè)特殊的容器HashMultmap,可以簡(jiǎn)單的將它的數(shù)據(jù)結(jié)構(gòu)理解為Map<K,?Set<V>>,今天主要介紹下基礎(chǔ)的知識(shí)點(diǎn)?HashMultmap級(jí)使用,感興趣的朋友一起看看吧
    2022-05-05
  • idea安裝jerbel及文件上傳下載的實(shí)現(xiàn)示例

    idea安裝jerbel及文件上傳下載的實(shí)現(xiàn)示例

    JRebel是一個(gè)Java開(kāi)發(fā)工具,它是一款用于實(shí)時(shí)代碼重載的插件,本文主要介紹了idea安裝jerbel及文件上傳下載的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解下
    2023-09-09
  • 剖析Java中HashMap數(shù)據(jù)結(jié)構(gòu)的源碼及其性能優(yōu)化

    剖析Java中HashMap數(shù)據(jù)結(jié)構(gòu)的源碼及其性能優(yōu)化

    這篇文章主要介紹了Java中HashMap數(shù)據(jù)結(jié)構(gòu)的源碼及其性能優(yōu)化,文中以Java 8后HashMap的性能提升來(lái)討論了HashMap的一些優(yōu)化點(diǎn),需要的朋友可以參考下
    2016-05-05

最新評(píng)論