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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【数据结构】图的存储结构—邻接矩阵

發(fā)布時間:2023/12/20 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【数据结构】图的存储结构—邻接矩阵 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

圖的類型&存儲結(jié)構(gòu)的介紹

鄰接矩陣

— 無向圖、有向圖的鄰接矩陣定義

— 網(wǎng)的鄰接矩陣的定義

鄰接矩陣:類的描述

鄰接矩陣:基本操作

1)創(chuàng)建圖

2)創(chuàng)建無向網(wǎng)

?3)創(chuàng)建有向網(wǎng)

4)頂點定位

5)查詢第一個鄰接點

6)查找下一個鄰接點

創(chuàng)作不易,不妨點贊💚評論??收藏💙一下


💟作者簡介:大家好呀!我是路遙葉子,大家可以叫我葉子哦!???? ?
📝個人主頁:【路遙葉子的博客】
🏆博主信息:四季輪換葉,一路招搖勝!

?????????????? 專欄

??????? 【安利Java零基礎(chǔ)】

??????? 【數(shù)據(jù)結(jié)構(gòu)-Java語言描述】

🐋希望大家多多支持😘一起進步呀!~??
🌈若有幫助,還請【關(guān)注?點贊?收藏】,不行的話我再努力努力呀!💪
————————————————
🍁想尋找共同成長的小伙伴,請點擊【Java全棧開發(fā)社區(qū)】

?前言

由于圖的結(jié)構(gòu)比較復雜,任意兩個頂點之間都可能存在關(guān)系(邊),無法通過存儲位置表示這種任意的邏輯關(guān)系,所以,圖無法采用順序存儲結(jié)構(gòu)。這一點同其他數(shù)據(jù)結(jié)構(gòu)(如線性表、樹)不同。

因為圖中的頂點具有相對概念,沒有固定的位置,且頂點和頂點之間通過添加和刪除邊,維持著不同的關(guān)系。考慮圖的定義,圖是由頂點和邊組成的。所以,分別考慮如何存儲頂點和邊。圖常用的存儲結(jié)構(gòu)有鄰接矩陣、鄰接表、十字鏈表和鄰接多重表。那么對于一般情況下該怎么存儲圖的數(shù)據(jù)結(jié)構(gòu)呢?這里我們主要分兩個章節(jié)詳細介紹兩種常用的圖存儲結(jié)構(gòu) — 鄰接矩陣、鄰接表


圖的類型&存儲結(jié)構(gòu)的介紹

  • 圖的類型主要有4種:無向圖、有向圖、無向網(wǎng)和有向網(wǎng)。
  • 可以用枚舉表示為:
public enum GraphKind{UDG, //無向圖(UnDirected Graph)DG, //有向圖(Directed Graph)UDN, //無向網(wǎng)(UnDirected Network)DN, //有向網(wǎng)(Directed Network) }

圖有多種存儲結(jié)構(gòu),每種存儲結(jié)構(gòu)都能表示上面的4種的類型。圖的存儲結(jié)構(gòu)除了存儲圖中各個頂點的信息外,還需要存儲與頂點相關(guān)的邊的信息。

常見圖的存儲結(jié)構(gòu):

  • 鄰接矩陣

  • 鄰接表

  • 鄰接多重表

  • 十字鏈表


鄰接矩陣

— 無向圖、有向圖的鄰接矩陣定義

邏輯結(jié)構(gòu)分為兩部分:V和E集合,其中,V是頂點,E是邊。因此,用一個一維數(shù)組存放圖中所有頂點數(shù)據(jù);用一個二維數(shù)組存放頂點間關(guān)系(邊或弧)的數(shù)據(jù),這個二維數(shù)組稱為鄰接矩陣。鄰接矩陣又分為有向圖鄰接矩陣和無向圖鄰接矩陣。

圖的鄰接矩陣:用來表示頂點之間相鄰關(guān)系的矩陣。

  • 圖G=(V, E)具有n(n >= 1)個頂點,頂點的順序依次為{v0,v1,...,vn-1}

  • 設圖A=(V,E)有n個頂點,則關(guān)于頂點數(shù)據(jù)的一維數(shù)組為:

  • 則圖G的鄰接矩陣A是一個n階方陣,定義如下:

特點1:無向圖 的鄰接矩陣一定是對稱 的,而 有向圖 的鄰接矩陣不一定對稱

因此,用?對無向圖而言,鄰接矩陣一定是對稱的,而且主對角線一定為零,副對角線不一定為0,有向圖則不一定如此。

鄰接矩陣來表示一個具有n個頂點的有向圖時需要n^2個單元來存儲鄰接矩陣;對有n個頂點的無向圖則只需存入上(下)三角陣中剔除了左上右下對角線上的0元素后剩余的元素壓縮存儲,故只需1+2+...+(n-1)=n(n-1)/2個單元。

特點2:無向圖鄰接矩陣的 第i行(或第i列)非零元素的個數(shù) 正好是第i個頂點的度。

度(Degree):一個頂點的度是指與該頂點相關(guān)聯(lián)的邊的條數(shù),頂點v的度記作d(v)”

無向圖,沒有方向,所有兩個頂點連線必定是相互的。因此行或列的非零元素個數(shù)必定一樣。則找頂點的度時,看行或列都可以。

特點3:

  • 有向圖頂點的度【行表示出度,列表示入度】
  • 頂點v入邊數(shù)目是該頂點的入度,記為ID(v);
  • 頂點v的出邊數(shù)目是該頂點的出度,記為OD(v);
  • 頂點v的度等于它的入度和出度之和,即D(v)=ID(v)+OD(v)

有向圖鄰接矩陣中第i行非零元素的個數(shù)為第i個頂點的出度,第i列非零元素的個數(shù)為第i個頂點的入度,第i個頂點的度為第i行與第i列非零元素個數(shù)之和。

特點4:用鄰接矩陣表示圖,很容易看出確定圖中任意兩個頂點是否有邊相連。

無向圖的鄰接矩陣是對稱的,一般可以采用壓縮存儲


— 網(wǎng)的鄰接矩陣的定義

網(wǎng)(network):帶權(quán)的圖

?圖與網(wǎng)的區(qū)別:

????????????????1. 權(quán)值:網(wǎng)里面對應的邊是有權(quán)值的,用以表示邊的某種屬性比如距離等。而圖的邊是沒有權(quán)值的

??????????????? 2. 表示零元素的形式不同:不管是無向圖還是有向圖表示零元素時,都用0代替表示;而在網(wǎng)中,表示零元素則是用無窮大∞ 表示。

無向網(wǎng)的鄰接矩陣:

?有向網(wǎng)的鄰接矩陣 :


鄰接矩陣:類的描述

public class MGraph implements IGraph {public final static int INFINITY = Integer.MAX_VALUE;private GraphKind kind; //圖的種類標志private int vexNum, arcNum; //圖的當前頂點數(shù)和邊數(shù)private Object[] vexs; //頂點集private int[][] arcs; //鄰接矩陣(邊集)public void createGraph(){} //創(chuàng)建圖private void createUDG() {} //創(chuàng)建無向圖private void createDG() {} //創(chuàng)建有向圖private void createUDN() {} //創(chuàng)建無向網(wǎng)private void createDN() {} //創(chuàng)建有向網(wǎng)public int getVexNum() { //返回定點數(shù)return vexNum;}public int getArcNum() { //返回邊數(shù)return arcNum;}// 給定頂點的值vex,返回其在圖中的位置,如果圖中不包含此頂點,則返回-1public int locateVex(Object vex) {}// 返回v表示結(jié)點的值,0 <= v <= vexNumpublic Object getVex(int v) throws Exception {}// 返回v的第一個鄰接點,若v沒有鄰接點則返回-1。其中 0 <= v <= vexNumpublic int firstAdjVex(int v) throws Exception {}// 返回v相對于w的下一個鄰接點,若w是v的最后一個鄰接點,則返回-1。其中 0 <= v,w <= vexNumpublic int nextAdjVex(int v, int w) throws Exception {} }

鄰接矩陣:基本操作

1)創(chuàng)建圖

// 創(chuàng)建圖public void createGraph() {// 獲得用戶輸入的圖的類型Scanner sc = new Scanner(System.in);System.out.println("請輸入圖的類型:");GraphKind kind = GraphKind.valueOf(sc.next()); //通過字符串獲得對應枚舉類型switch (kind) { //根據(jù)不同的枚舉值,選擇不同的圖或網(wǎng)的創(chuàng)建case UDG:createUDG(); // 構(gòu)建無向圖return;case DG:createDG(); // 構(gòu)建有向圖return;case UDN:createUDN(); // 構(gòu)建無向網(wǎng)return;case DN:createDN(); // 構(gòu)建有向網(wǎng)return;}}

2)創(chuàng)建無向網(wǎng)

  • 輸入圖的頂點、邊及權(quán)值構(gòu)造無向圖,步驟:

  • 輸入頂點數(shù)或邊數(shù)

  • 根據(jù)圖的頂點數(shù)構(gòu)建鄰接矩陣

  • 根據(jù)圖的邊數(shù),確定輸入邊的數(shù)目

  • 根據(jù)輸入每條邊的頂點再鄰接矩陣相應位置保存每條邊的權(quán)值。

  • 代碼

private void createUDN() {//初始化變量Scanner sc = new Scanner(System.in);System.out.println("請分別輸入圖的頂點數(shù)、圖的邊數(shù):");vexNum = sc.nextInt();//頂點數(shù)narcNum = sc.nextInt();//邊數(shù)e//輸入圖中各頂點vexs = new Object[vexNum]; //頂點集對應的數(shù)組System.out.println("請分別輸入圖的各個頂點:");for (int v = 0; v < vexNum; v++) //通過循環(huán)依次輸入各個頂點vexs[v] = sc.next();//定義鄰接矩陣arcs = new int[vexNum][vexNum];// 初始化鄰接矩陣for (int v = 0; v < vexNum; v++)for (int u = 0; u < vexNum; u++)arcs[v][u] = INFINITY; //初始為無窮大//輸入邊信息System.out.println("請輸入各個邊的兩個頂點及其權(quán)值:");for (int k = 0; k < arcNum; k++) {int v = locateVex(sc.next()); //頂點int u = locateVex(sc.next()); //頂點arcs[v][u] = arcs[u][v] = sc.nextInt(); //權(quán)值, 對稱} }

?3)創(chuàng)建有向網(wǎng)

// 構(gòu)建有向網(wǎng)private void createDN() {Scanner sc = new Scanner(System.in);System.out.println("請分別輸入圖的頂點數(shù)、圖的邊數(shù):");vexNum = sc.nextInt();arcNum = sc.nextInt();vexs = new Object[vexNum];System.out.println("請分別輸入圖的各個頂點:");for (int v = 0; v < vexNum; v++)//構(gòu)造頂點向量vexs[v] = sc.next();arcs = new int[vexNum][vexNum];for (int v = 0; v < vexNum; v++)// 初始化鄰接矩陣for (int u = 0; u < vexNum; u++)arcs[v][u] = INFINITY;System.out.println("請輸入各個邊的兩個頂點及其權(quán)值:");for (int k = 0; k < arcNum; k++) {int v = locateVex(sc.next());int u = locateVex(sc.next());arcs[v][u] = sc.nextInt(); //僅設置頂點v-->頂點u,不是對稱的,只需要設置一個}}

4)頂點定位

  • 根據(jù)頂點信息vex,取得其在頂點數(shù)組中的位置,若圖中無此頂點,則返回-1。

  • 代碼:

// 根據(jù)頂點信息vex,取得其在頂點數(shù)組中的位置,若圖中無此頂點,則返回-1。public int locateVex(Object vex) {// 遍歷頂點數(shù)組for (int v = 0; v < vexNum; v++)if (vexs[v].equals(vex))return v;return -1;}
  • 時間復雜度:O(n)

5)查詢第一個鄰接點

步驟:

  • 判斷v的合法性
  • 頂點v的索引號,對應鄰接矩陣的第v行,遍歷第v行,查找是否有非0、非無窮大值的元素

  • 代碼:

// 已知圖中的一個頂點v,返回v的第一個鄰接點,如果v沒有連接點,則返回-1,其中0 <= v < vexNum public int firstAdjVex(int v) throws Exception {if (v < 0 || v >= vexNum)throw new Exception("第" + v + "個頂點不存在!");for (int j = 0; j < vexNum; j++)if (arcs[v][j] != 0 && arcs[v][j] < INFINITY)return j;return -1; }
  • 時間復雜度:O(n)

6)查找下一個鄰接點

步驟:

  • 判斷v的合法性

  • 從鄰接矩陣第v行第w+1列開始遍歷查找是否有非0、非無窮大值的元素
  • 代碼:

public int nextAdjVex(int v, int w) throws Exception {if (v < 0 || v >= vexNum)throw new Exception("第" + v + "個頂點不存在!");for (int j = w + 1; j < vexNum; j++)if (arcs[v][j] != 0 && arcs[v][j] < INFINITY)return j;return -1; }
  • 時間復雜度:O(n)

寫到最后

四季輪換,已經(jīng)數(shù)不清凋零了多少, 愿我們往后能向心而行,一路招搖勝!

🐋 你的支持認可是我創(chuàng)作的動力

💟 創(chuàng)作不易,不妨點贊💚評論??收藏💙一下

😘 感謝大佬們的支持,歡迎各位前來不吝賜教

想要了解更多嗎?沒時間解釋了,快來點一點!

路遙葉子的博客_CSDN博客-數(shù)據(jù)結(jié)構(gòu),安利Java零基礎(chǔ),spring領(lǐng)域博主路遙葉子擅長數(shù)據(jù)結(jié)構(gòu),安利Java零基礎(chǔ),spring,等方面的知識,路遙葉子關(guān)注spring,java,maven,elementui,vue.js,mysql,數(shù)據(jù)結(jié)構(gòu)領(lǐng)域.https://blog.csdn.net/zsy3757486?spm=1010.2135.3001.5343

總結(jié)

以上是生活随笔為你收集整理的【数据结构】图的存储结构—邻接矩阵的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。