欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Java實(shí)現(xiàn)無(wú)向環(huán)和有向環(huán)的檢測(cè)

 更新時(shí)間:2022年04月06日 11:07:41   作者:之一Yo  
這篇文章主要介紹了如何在?Java?中實(shí)現(xiàn)無(wú)向環(huán)和有向環(huán)的檢測(cè),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下

無(wú)向環(huán)

一個(gè)含有環(huán)的無(wú)向圖如下所示,其中有兩個(gè)環(huán),分別是 0-2-1-0 和 2-3-4-2:

要檢測(cè)無(wú)向圖中的環(huán),可以使用深度優(yōu)先搜索。假設(shè)從頂點(diǎn) 0 出發(fā),再走到相鄰的頂點(diǎn) 2,接著走到頂點(diǎn) 2 相鄰的頂點(diǎn) 1,由于頂點(diǎn) 0 和頂點(diǎn) 1 相鄰,并且頂點(diǎn) 0 被標(biāo)記過了,說(shuō)明我們饒了一圈,所以無(wú)向圖中存在環(huán)。雖然頂點(diǎn) 2 和頂點(diǎn) 1 相鄰,但是并不能說(shuō)明存在環(huán),因?yàn)槲覀兙褪菑捻旤c(diǎn) 2 直接走到頂點(diǎn) 1 的,這二者只有邊的關(guān)系。算法如下所示:

package com.zhiyiyo.graph;

import com.zhiyiyo.collection.stack.LinkStack;
import com.zhiyiyo.collection.stack.Stack;

/**
 * 無(wú)向圖中的環(huán)
 */
public class Cycle {
    private boolean[] marked;
    private Graph graph;
    private boolean hasCycle;

    public Cycle(Graph graph) {
        this.graph = graph;
        marked = new boolean[graph.V()];

        for (int v = 0; v < graph.V(); ++v) {
            if (!marked[v]) {
                dfs(v);
            }
        }
    }

    private void dfs(int s) {
        if (hasCycle()) return;

        Stack<Integer> vertexes = new LinkStack<>();
        vertexes.push(s);
        marked[s] = true;

        int lastVertex = s;
        while (!vertexes.isEmpty()) {
            int v = vertexes.pop();

            for (int w : graph.adj(v)) {
                if (!marked[w]) {
                    marked[w] = true;
                    vertexes.push(w);
                } else if (w != lastVertex) {
                    hasCycle = true;
                    return;
                }
            }

            lastVertex = v;
        }
    }

    /**
     * 圖中是否有環(huán)
     */
    public boolean hasCycle() {
        return hasCycle;
    }
}

有向環(huán)

有向圖

有向圖的實(shí)現(xiàn)方式和上一篇博客 《如何在 Java 中實(shí)現(xiàn)無(wú)向圖》 中無(wú)向圖的實(shí)現(xiàn)方式幾乎一樣,只是在添加邊 v-w 時(shí)只在頂點(diǎn) v 的鏈表上添加頂點(diǎn) w,而不對(duì)頂點(diǎn) w 的鏈表進(jìn)行操作。如果把 LinkGraph 中成員變量的訪問權(quán)限改成 protected,只需繼承并重寫 addEdge 方法即可:

package com.zhiyiyo.graph;


public class LinkDigraph extends LinkGraph implements Digraph {

    public LinkDigraph(int V) {
        super(V);
    }

    @Override
    public void addEdge(int v, int w) {
        adj[v].push(w);
        E++;
    }

    @Override
    public Digraph reverse() {
        Digraph digraph = new LinkDigraph(V());
        for (int v = 0; v < V(); ++v) {
            for (int w : adj(v)) {
                digraph.addEdge(w, v);
            }
        }
        return digraph;
    }
}

檢測(cè)算法

一個(gè)含有有向環(huán)的有向圖如下所示,其中 5-4-3-5 構(gòu)成了一個(gè)環(huán):

這里使用遞歸實(shí)現(xiàn)的深度優(yōu)先搜索來(lái)檢測(cè)有向環(huán)。假設(shè)從頂點(diǎn) 0 開始走,一路經(jīng)過 5、4、3 這三個(gè)頂點(diǎn),最終又碰到了與頂點(diǎn) 3 相鄰的頂點(diǎn) 5,這時(shí)候如果知道頂點(diǎn) 5 已經(jīng)被訪問過了,并且遞歸函數(shù)還被壓在棧中,就說(shuō)明深度優(yōu)先搜索從頂點(diǎn) 5 開始走,又回到了頂點(diǎn) 5,也就是找到了有向環(huán)。算法如下所示:

package com.zhiyiyo.graph;

import com.zhiyiyo.collection.stack.LinkStack;
import com.zhiyiyo.collection.stack.Stack;

/**
 * 有向圖中的環(huán)
 */
public class DirectedCycle {
    private boolean[] marked;
    private boolean[] onStack;
    private int[] edgeTo;
    private Graph graph;
    private Stack<Integer> cycle;

    public DirectedCycle(Digraph graph) {
        this.graph = graph;
        marked = new boolean[graph.V()];
        onStack = new boolean[graph.V()];
        edgeTo = new int[graph.V()];

        for (int v = 0; v < graph.V(); ++v) {
            if (!marked[v]) {
                dfs(v);
            }
        }
    }

    private void dfs(int v) {
        marked[v] = true;
        onStack[v] = true;

        for (int w : graph.adj(v)) {
            if (hasCycle()) return;
            if (!marked[w]) {
                marked[w] = true;
                edgeTo[w] = v;
                dfs(w);
            } else if (onStack[w]) {
                cycle = new LinkStack<>();
                cycle.push(w);
                for (int i = v; i != w; i = edgeTo[i]) {
                    cycle.push(i);
                }
                cycle.push(w);
            }
        }

        onStack[v] = false;
    }

    /**
     * 圖中是否有環(huán)
     */
    public boolean hasCycle() {
        return cycle != null;
    }

    /**
     * 圖中的一個(gè)環(huán)
     */
    public Iterable<Integer> cycle() {
        return cycle;
    }
}

以上就是基于Java實(shí)現(xiàn)無(wú)向環(huán)和有向環(huán)的檢測(cè)的詳細(xì)內(nèi)容,更多關(guān)于Java無(wú)向環(huán) 有向環(huán)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • spring?cloud中Feign導(dǎo)入jar失敗的問題及解決方案

    spring?cloud中Feign導(dǎo)入jar失敗的問題及解決方案

    這篇文章主要介紹了spring?cloud中Feign導(dǎo)入jar失敗的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • springboot整合RabbitMQ發(fā)送短信的實(shí)現(xiàn)

    springboot整合RabbitMQ發(fā)送短信的實(shí)現(xiàn)

    本文會(huì)和SpringBoot做整合,實(shí)現(xiàn)RabbitMQ發(fā)送短信,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • spring事務(wù)之事務(wù)掛起和事務(wù)恢復(fù)源碼解讀

    spring事務(wù)之事務(wù)掛起和事務(wù)恢復(fù)源碼解讀

    這篇文章主要介紹了spring事務(wù)之事務(wù)掛起和事務(wù)恢復(fù)源碼解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Java編程中void方法的學(xué)習(xí)教程

    Java編程中void方法的學(xué)習(xí)教程

    這篇文章主要介紹了Java編程中void方法的學(xué)習(xí)教程,包括對(duì)void方法進(jìn)行單元測(cè)試,需要的朋友可以參考下
    2015-10-10
  • 使用Logback設(shè)置property參數(shù)方式

    使用Logback設(shè)置property參數(shù)方式

    這篇文章主要介紹了使用Logback設(shè)置property參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Spring加載配置和讀取多個(gè)Properties文件的講解

    Spring加載配置和讀取多個(gè)Properties文件的講解

    今天小編就為大家分享一篇關(guān)于Spring加載配置和讀取多個(gè)Properties文件的講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • 通過Java 程序獲取Word中指定圖片的坐標(biāo)位置

    通過Java 程序獲取Word中指定圖片的坐標(biāo)位置

    本文介紹通過Java程序獲取Word文檔中指定圖片的坐標(biāo)位置,程序運(yùn)行環(huán)境是jdk1.8開發(fā)環(huán)境idea,通過java程序代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-05-05
  • Spring配置文件的超詳細(xì)圖文介紹

    Spring配置文件的超詳細(xì)圖文介紹

    Spring配置文件是一個(gè)或多個(gè)標(biāo)準(zhǔn)的XML文檔,下面這篇文章主要給大家介紹了關(guān)于Spring配置文件的超詳細(xì)圖文介紹,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • 如何在SpringBoot 中使用 Druid 數(shù)據(jù)庫(kù)連接池

    如何在SpringBoot 中使用 Druid 數(shù)據(jù)庫(kù)連接池

    這篇文章主要介紹了SpringBoot 中使用 Druid 數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)步驟,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot,感興趣的朋友可以了解下
    2021-03-03
  • java中volatile和synchronized的區(qū)別與聯(lián)系

    java中volatile和synchronized的區(qū)別與聯(lián)系

    這篇文章主要介紹了java中volatile和synchronized的區(qū)別與聯(lián)系的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10

最新評(píng)論