數(shù)據(jù)結(jié)構(gòu)-圖

數(shù)據(jù)結(jié)構(gòu) - 圖


目錄:

  • 基本概念
    • 無向圖
    • 有向圖
  • 儲存結(jié)構(gòu)
    • 鄰接矩陣
    • 鄰接表
    • 十字鏈表(有向圖)
    • 鄰接多重表(無向圖)
  • 圖的遍歷
    • 深度優(yōu)先搜索
    • 廣度優(yōu)先搜索
    • 最小生成樹
      • 普里姆算法(Prim)
      • 克魯斯卡爾算法(Kruskal)
  • 最后

基本概念

圖是由結(jié)點和他們之間連線的集合

無向圖

無向圖.png

無向圖解析.png
  • 連通圖:當(dāng)任意一個結(jié)點都能直接或間接到其他全部結(jié)點的時候,就稱為連通圖
  • 完全圖:邊數(shù) = 頂點數(shù) *( 頂點數(shù) - 1 ) / 2
  • 生成樹 : 邊數(shù) = 頂點數(shù) - 1

有向圖

有向圖.png
有向圖解析.png
  • 上圖,V1的出度是2,入度是1
  • 權(quán)值:一條連線所代表的值
  • 當(dāng)兩個結(jié)點互相指向,那么就等于一條直線

儲存結(jié)構(gòu)

儲存結(jié)構(gòu).png

鄰接矩陣

使用數(shù)組的形式來儲存數(shù)據(jù)

  • 在有向圖中,當(dāng)一個頂點能夠指向另外一個頂點,則矩陣中的值為1,否則為0
有向圖鄰接矩陣.png
  • 在無向圖中,邊是相當(dāng)于兩個頂點相互指向
無向圖鄰接矩陣.png
  • 代碼中鄰接矩陣表示 : int[][] martix ;

鄰接表

使用頂點以及其弧的指向來儲存數(shù)據(jù)

鄰接表存儲.png
  • 頂點索引:頂點的唯一標(biāo)識
  • 出弧鏈表頭指針: 頂點指向其他頂點的連接
  • 頂點數(shù)據(jù):頂點儲存的數(shù)據(jù)
    </br>
  • 在代碼中,鄰接表的結(jié)構(gòu)表示
鄰接表代碼構(gòu)造.png

十字鏈表(有向圖)

使用頂點以及其弧的指向來儲存數(shù)據(jù)

十字鏈表數(shù)據(jù)儲存.png

這里以V1頂點為例說明:

  • 頂點索引:0
  • 頂點數(shù)據(jù):1(假定的)
  • 以該頂點為弧尾的弧的結(jié)點指針: V1 -> V3, V1 -> V2, V1 -> V4
  • 以該頂點為弧頭的弧的結(jié)點指針: V4 -> V1
    這里以V1 -> V4 的弧為例說明:
  • 弧尾頂點索引:0
  • 弧頭頂點索引:3
  • 弧尾相同的下一條弧的指針: V1 -> V2 , V1 -> V3
  • 弧頭相同的下一條弧的指針: V3 -> V4
  • 弧的數(shù)據(jù):V1V4(假定的)
    </br>
  • 代碼實現(xiàn)的結(jié)構(gòu):
十字鏈表代碼構(gòu)造.png

鄰接多重表(無向圖)

使用頂點以及邊的連接指向來儲存數(shù)據(jù)

鄰接多重表數(shù)據(jù)儲存.png

頂點表示很清晰簡單
這里以V1 ->V4邊為例說明:

  • A點索引 : 0(V1)
  • B點索引:3 (V4)
  • 與A點相連接的下一條邊的指針: V1 -> V2 或者 V1 -> V3, 取決于哪一條更早建立連接
  • 與B點相連接的下一條邊的指針 : V3 -> V4
    </br>
  • 代碼實現(xiàn)的結(jié)構(gòu):
鄰接多重表代碼構(gòu)造.png

圖的遍歷

實例-圖.png

深度優(yōu)先搜索

對于上圖
A頂點開始進(jìn)行深度優(yōu)先搜索的順序為:
A - B - C - E - F - D - G - H
丟棄了 F - B , H -D 這兩條邊,形成了一棵樹

  • 規(guī)則:
    順著一個頂點不斷向下搜索,當(dāng)搜索到的頂點與前面搜索過的頂點形成環(huán)的時候就停止
    有點類似樹的前序遍歷

廣度優(yōu)先搜索

對于上圖
A頂點開始進(jìn)行廣度優(yōu)先搜索的順序為:
A - B - D - C - F - G - H - E
丟棄了E - F 和 G - H 這兩條邊,形成了一棵樹

  • 規(guī)則:
    按層來不斷進(jìn)行搜索

最小生成樹

當(dāng)遍歷的時候涉及邊的權(quán)值問題,就要使用最小生成樹來解決

最小生成樹前.png

如圖:上面的數(shù)值是邊的權(quán)值,可以理解為修路的成本,每個頂點可以理解為一個城市,如何最節(jié)約成本完成城市之間的連通就需要使用最小生成樹。
最小生成樹后:

最小生成樹后.png

普里姆算法(Prim)

普里姆算法(Prim).png

過程:

  1. 選定一個點A,放入點集合
  2. 關(guān)于A的所有的邊放入 待選邊集合
  3. 待選邊集合選取權(quán)值最小的邊 A - F (1),放入邊集合
  4. 邊集合中提取出未在點集合的點F,放入點集合
  5. 刷新待選邊集合,列出所有AF有關(guān)的邊
  6. 選出權(quán)值最小不會與當(dāng)前已選邊形成閉環(huán)的邊,然后放入邊集合
  7. 以此類推,得出所有,既是最小生成樹

Prim算法后:

普里姆算法(Prim)后.png

克魯斯卡爾算法(Kruskal)

克魯斯卡爾算法(Kruskal).png

過程:

  1. 列出所有邊的集合
  2. 依次選取權(quán)值最小的邊,同時將涉及的點加入點集合
  3. 選取的邊不能與已選邊構(gòu)成閉合
  4. 當(dāng)點集合中出現(xiàn)了所有點以后,需要讓所有點能連通,形成生成樹(邊 = 點 - 1)

Kruskal算法后:

克魯斯卡爾算法(Kruskal)后.png

最后
對數(shù)據(jù)結(jié)構(gòu)的基本認(rèn)識和理解到這里就結(jié)束了
關(guān)于圖的代碼實現(xiàn),在有了隊列,棧,線性表的實踐過后,代碼的轉(zhuǎn)換肯定是沒問題的
重點在于對上面所說知識點的深入理解和邏輯轉(zhuǎn)換
再次感謝慕課網(wǎng)的James老師
PS:
后面我會寫一寫,從零開始的Android組件化開發(fā)的記錄博文

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容