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

Java數(shù)據(jù)結構中圖的進階詳解

 更新時間:2022年01月28日 16:25:26   作者:龍弟-idea  
在Java學習與應用中,數(shù)據(jù)結構無疑是每個人都要接觸的難點,為了更好的學習數(shù)據(jù)結構這一塊內容,用圖來理解便是最好的方式,讓我們一起來了解本篇內容圖的進階

有向圖

有向圖的定義及相關術語

定義∶ 有向圖是一副具有方向性的圖,是由一組頂點和一組有方向的邊組成的,每條方向的邊都連著 一對有序的頂點。

出度∶ 由某個頂點指出的邊的個數(shù)稱為該頂點的出度。

入度: 指向某個頂點的邊的個數(shù)稱為該頂點的入度。

有向路徑︰ 由一系列頂點組成,對于其中的每個頂點都存在一條有向邊,從它指向序列中的下一個頂點。

有向環(huán)∶ —條至少含有一條邊,且起點和終點相同的有向路徑。

一副有向圖中兩個頂點v和w可能存在以下四種關系:

1.沒有邊相連;

⒉存在從v到w的邊v—>w;

3.存在從w到v的邊w—>V;

4.既存在w到v的邊,也存在v到w的邊,即雙向連接;

理解有向圖是一件比較簡單的,但如果要通過眼睛看出復雜有向圖中的路徑就不是那么容易了。

有向圖API設計

 在api中設計了一個反向圖,其因為有向圖的實現(xiàn)中,用adj方法獲取出來的是由當前頂點v指向的其他頂點,如果能得到其反向圖,就可以很容易得到指向v的其他頂點。

有向圖的實現(xiàn)

// 有向圖
 
public class Digraph {
    // 記錄頂點的數(shù)量
     
    private final int V;
 
    //記錄邊的數(shù)量
    private int E;
 
    //定義有向圖的鄰接表
    private Queue <Integer>[] adj;
 
    public Digraph (int v) {
        //初始化頂點數(shù)量
        this.V = v;
        //初始化邊的數(shù)量
        this.E = 0;
        //初始化鄰接表
        adj = new LinkedList[v];
        //初始化鄰接表的空隊列
        for (int i = 0; i < v; i++) {
            adj[i] = new LinkedList<>();
        }
    }
    public int V () {
        return V;
    }
    public int E () {
        return E;
    }
 
    //添加一條 v -> w的有向邊
    public void addEage (int v , int w) {
        adj[v].add(w);
        ++E;
    }
 
    //獲取頂點v 指向的 所有頂點
    public Queue<Integer> adj (int v) {
        return adj[v];
    }
 
    //將有向圖 反轉 后返回
    public Digraph reverse () {
        //創(chuàng)建一個反向圖
        Digraph reverseDigraph = new Digraph(V);
        //獲取原來有向圖的每個結點
        for (int i = 0; i < V; i++) {
            //獲取每個結點 鄰接表的所有結點
            for (Integer w : adj[i]) {
                //反轉圖記錄下 w -> v
                reverseDigraph.adj(w).add(i);
            }
        }
        return reverseDigraph;
    }
}
 

拓撲排序

在現(xiàn)實生活中,我們經(jīng)常會同一時間接到很多任務去完成,但是這些任務的完成是有先后次序的。以我們學習java學科為例,我們需要學習很多知識,但是這些知識在學習的過程中是需要按照先后次序來完成的。從java基礎,到jsp/servlet,到ssm,到springboot等是個循序漸進且有依賴的過程。在學習jsp前要首先掌握java基礎和html基礎,學習ssm框架前要掌握jsp/servlet之類才行。

 為了簡化問題,我們使用整數(shù)為頂點編號的標準模型來表示這個案例:

此時如果某個同學要學習這些課程,就需要指定出一個學習的方案,我們只需要對圖中的頂點進行排序,讓它轉換為一個線性序列,就可以解決問題,這時就需要用到一種叫拓撲排序的算法。

拓撲排序圖解

給定一副有向圖,將所有的頂點排序,使得所有的有向邊均從排在前面的元素指向排在后面的元素,此時就可以明確的表示出每個頂點的優(yōu)先級。下列是一副拓撲排序后的示意圖︰

檢測有向圖中的環(huán)

如果學習x課程前必須先學習y課程,學習y課程前必須先學習z課程,學習z課程前必須先學習x課程,那么一定是有問題了,我們就沒有辦法學習了,因為這三個條件沒有辦法同時滿足。其實這三門課程x、y、z的條件組成了一個環(huán)︰

因此,如果我們要使用拓撲排序解決優(yōu)先級問題,首先得保證圖中沒有環(huán)的存在。

檢測有向環(huán)的API設計

檢測有向環(huán)實現(xiàn)

在API中添加了onStack[]布爾數(shù)組,索引為圖的頂點,當我們深度搜索時︰

1.在如果當前頂點正在搜索,則把對應的onStack數(shù)組中的值改為true,標識進棧;

2.如果當前頂點搜索完畢,則把對應的onStack數(shù)組中的值改為false,標識出棧;

3.如果即將要搜索某個頂點,但該頂點已經(jīng)在棧中,則圖中有環(huán);

代碼

 
/**
 *  檢查圖中是否存在環(huán)
 */
public class DirectedCycle {
    /**
     * 索引代表頂點,用來記錄頂點是否被搜索過
     */
    private boolean[] marked;
 
    /**
     * 判斷圖中是否有環(huán)
     */
    private boolean hasCycle;
 
    /**
     * 采用棧的思想,記錄當前頂點是否已經(jīng)存在 當前搜索的的路徑上
     * 存在則可以判斷 圖中是存在環(huán)的
     */
    private boolean[] onStack;
 
    /**
     * 判斷傳入的有向圖 是否存在環(huán)
     * @param G
     */
    public DirectedCycle (Digraph G) {
        marked = new boolean[G.V()];
        onStack = new boolean[G.V()];
        hasCycle = false;
        //因為不知道從那個點出發(fā) 可能存在環(huán)
        //所以需要從所有的頂點都出發(fā)搜索 判斷是否存在環(huán)
        for (int i = 0; i < G.V(); i++) {
            dfs(G,i);
        }
    }
 
    /**
     * 采用深度搜索 判斷有向圖是否存在環(huán)
     * onStack 入棧出棧 然后判斷當前搜索的頂點是否已經(jīng)在搜索路徑上
     *
     * @param G
     * @param v
     */
    private void dfs (Digraph G,int v) {
        //標記頂點已經(jīng)搜索過
        marked[v] = true;
        for (Integer adj : G.adj(v)) {
            //判斷v 是否已經(jīng)在搜索的路徑上了
            if(marked[adj] && onStack[adj]) {
                //存在環(huán)
                hasCycle = true;
            }else {
                //采用回溯的思路
                //讓頂點入棧
                onStack[adj] = true;
                dfs(G,adj);
                //回溯 頂點出棧
                onStack[adj] = false;
            }
        }
    }
 
    /**
     * 判斷是否存在環(huán)
     * @return
     */
    public boolean hasCycle(){
        return hasCycle;
    }
 
}

基于深度優(yōu)先的頂點排序

如果要把圖中的頂點生成線性序列其實是一件非常簡單的事,之前我們學習并使用了多次深度優(yōu)先搜索,我們會發(fā)現(xiàn)其實深度優(yōu)先搜索有一個特點,那就是在一個連通子圖上,每個頂點只會被搜索一次,如果我們能在深度優(yōu)先搜索的基礎上,添加一行代碼,只需要將搜索的頂點放入到線性序列的數(shù)據(jù)結構中,我們就能完成這件事。

頂點排序API設計

頂點排序實現(xiàn)

在API的設計中,我們添加了一個棧reversePost用來存儲頂點,當我們深度搜索圖時,每搜索完畢一個頂點,把該頂點放入到reversePost中,這樣就可以實現(xiàn)頂點排序。

代碼:

 
/**
 * 深度優(yōu)先搜索 的頂點排序
 */
public class DepthFirstOrder {
    /**
     * 索引代表頂點 ,用來記錄頂點是否已經(jīng)被搜索過了
     */
    private boolean[] marked;
 
    /**
     * 使用棧記錄深度優(yōu)先搜索下的頂點
     */
    private Stack<Integer> reversePost;
 
    public DepthFirstOrder (Digraph G) {
        marked = new boolean[G.V()];
        reversePost = new Stack<>();
        for (int i = 0; i < G.V(); i++) {
            //如果頂點已經(jīng)被搜索過則不用
            if(!marked[i])
                dfs(G,i);
        }
    }
 
    /**
     * 基于深度優(yōu)先搜索,生成頂點線性序列
     * @param G
     * @param v
     */
    private void dfs (Digraph G, int v) {
        //標記頂點已經(jīng)被搜索過
        marked[v] =  true;
        for (Integer w : G.adj(v)) {
            if(!marked[w])
                dfs(G,w);
        }
        //記錄到線性序列中
        reversePost.push(v);
    }
 
    /**
     * 獲取頂點線性序列
     * @return
     */
    private Stack<Integer> ReversePost() {
        return reversePost;
    }
}

到此這篇關于Java數(shù)據(jù)結構中圖的進階詳解的文章就介紹到這了,更多相關Java 圖的進階內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java使用DSA密鑰對生成XML簽名的方法

    Java使用DSA密鑰對生成XML簽名的方法

    這篇文章主要介紹了Java使用DSA密鑰對生成XML簽名的方法,實例分析了java使用DSA密鑰對生成XML簽名的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • Spring使用xml方式整合第三方框架流程詳解

    Spring使用xml方式整合第三方框架流程詳解

    這篇文章主要介紹了Spring使用xml方式整合第三方框架流程,Spring會在應用上下文中為某個bean尋找其依賴的bean,Spring中bean有三種裝配機制,分別是:在xml中顯式配置、在java中顯式配置、隱式的bean發(fā)現(xiàn)機制和自動裝配
    2023-02-02
  • java使用Jdom實現(xiàn)xml文件寫入操作實例

    java使用Jdom實現(xiàn)xml文件寫入操作實例

    這篇文章主要介紹了java使用Jdom實現(xiàn)xml文件寫入操作的方法,以完整實例形式分析了Jdom針對XML文件寫入操作的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10
  • MyBatisPlus查詢投影與查詢條件詳細講解

    MyBatisPlus查詢投影與查詢條件詳細講解

    這篇文章主要介紹了MyBatisPlus DQL編程控制中的查詢投影、查詢條件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • 微服務搭建集成Spring Cloud Turbine詳解

    微服務搭建集成Spring Cloud Turbine詳解

    Spring Cloud是一系列框架的有序集合。它利用Spring Boot的開發(fā)便利性巧妙地簡化了分布式系統(tǒng)基礎設施的開發(fā),最終給開發(fā)者留出了一套簡單易懂、易部署和易維護的分布式系統(tǒng)開發(fā)工具包。下面我們來詳細了解一下吧
    2019-06-06
  • java和javascript中過濾掉img形式的字符串不顯示圖片的方法

    java和javascript中過濾掉img形式的字符串不顯示圖片的方法

    這篇文章主要介紹了java和javascript中過濾掉img形式的字符串不顯示圖片的方法,以實例形式分別講述了采用java和javascript實現(xiàn)過濾掉img形式字符串的技巧,需要的朋友可以參考下
    2015-02-02
  • spring boot優(yōu)雅集成redisson詳解

    spring boot優(yōu)雅集成redisson詳解

    這篇文章主要為大家介紹了spring boot優(yōu)雅集成redisson詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • 通過IDEA快速定位和排除依賴沖突問題

    通過IDEA快速定位和排除依賴沖突問題

    這篇文章主要介紹了通過IDEA快速定位和排除依賴沖突問題,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-06-06
  • Java獲取堆棧信息的三種方法小結

    Java獲取堆棧信息的三種方法小結

    在Java編程中,獲取堆棧信息對于調試和故障排除非常重要,Java提供了多種方式來獲取當前線程的堆棧信息,下面就跟隨小編一起學習一下常用的三種吧
    2024-03-03
  • springboot 使用QQ郵箱發(fā)送郵件的操作方法

    springboot 使用QQ郵箱發(fā)送郵件的操作方法

    這篇文章主要介紹了springboot使用QQ郵箱發(fā)送郵件功能,本文通過實例圖文相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-10-10

最新評論