【数据结构】图的存储结构—邻接矩阵
目錄
圖的類型&存儲結(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)。
- 可以用枚舉表示為:
圖有多種存儲結(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)值。
-
代碼
?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。
-
代碼:
-
時間復雜度:O(n)
5)查詢第一個鄰接點
步驟:
- 判斷v的合法性
-
頂點v的索引號,對應鄰接矩陣的第v行,遍歷第v行,查找是否有非0、非無窮大值的元素
-
代碼:
-
時間復雜度:O(n)
6)查找下一個鄰接點
步驟:
-
判斷v的合法性
- 從鄰接矩陣第v行第w+1列開始遍歷查找是否有非0、非無窮大值的元素
-
代碼:
- 時間復雜度: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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql server常用函数积累
- 下一篇: jvm经典文章整理