1. 程式人生 > >【圖(上)】什麼是圖,抽象資料型別,怎麼表示一個圖

【圖(上)】什麼是圖,抽象資料型別,怎麼表示一個圖

什麼是圖

  • 表示“多對多”的關係
  • 包含
    • 一組頂點:通常用V (Vertex) 表示頂點集合
    • 一組邊:通常用E (Edge) 表示邊的集合
      • 邊是頂點對: ( v , w
        ) E (v, w) \in\mathbb E
        ,其中 v
        , w V v, w \in\mathbb V
      • 有向邊< v, w> 表示從v指向w的邊(單行線)
      • 不考慮重邊和自迴路
        在這裡插入圖片描述

抽象資料型別定義

  • 型別名:圖(Graph)
  • 資料物件集:G(V,E)由一個非空的有限頂點集合V和一個有限邊集合E組成(頂點不為空,邊可以為空)。
  • 操作集:對於任意圖 G G r a p h G\in\mathbb Graph ,以及 v V v\in\mathbb V , e E e\in\mathbb E
    • Graph Create():建立並返回空圖;
    • Graph InsertVertex(Graph G, Vertex v):將v插入G;
    • Graph InsertEdge(Graph G, Edge e):將e插入G;
    • void DFS(Graph G, Vertex v):從頂點v出發深度優先遍歷圖G;
    • void BFS(Graph G, Vertex v):從頂點v出發寬度優先遍歷圖G;
    • void ShortestPath(Graph G, Vertex v, int Dist[]):計算圖G中頂點v到任意其他頂點的最短距離;
    • void MST(Graph G):計算圖G的最小生成樹;

常用術語

網路:就是邊上有權值的圖

在這裡插入圖片描述

怎麼在程式中表示一個圖

1、鄰接矩陣

在這裡插入圖片描述

問題:對於無向圖的儲存,怎樣可以省一半空間?
用一個長度為N(N+1)/2的1維陣列A儲存{G00,G10,G11,……,G(n-1)0,…,G(n-1)(n-1)},
則Gij在A中對應的下標是:

( i*(i+1)/2 + j )

對於網路,只要把G[i][j]的值定義為邊
<vi,vj>的權重即可。

鄰接矩陣優點

  • 直觀、簡單、好理解
  • 方便檢查任意一對頂點間是否存在邊
  • 方便找任一頂點的所有“鄰接點”(有邊直接相連的頂點)
  • 方便計算任一頂點的“度”(從該點發出的邊數為“出度”,指向該點的邊數為“入度”)
    • 無向圖:對應行(或列)非0元素的個數
    • 有向圖:對應行非0元素的個數是“出度”;對應列非0元素的個數是“入度”

鄰接矩陣缺點

  • 浪費空間—— 存稀疏圖(點很多而邊很少)有大量無效元素
    • 對稠密圖(特別是完全圖)還是很合算的
  • 浪費時間—— 統計稀疏圖中一共有多少條邊

2、鄰接表

在這裡插入圖片描述

鄰接表優缺點

  • 方便找任一頂點的所有“鄰接點”
  • 節約稀疏圖的空間
    • 需要N個頭指標+ 2E個結點(每個結點至少2個域)
  • 方便計算任一頂點的“度”?
    • 對無向圖:是的
    • 對有向圖:只能計算“出度”;需要構造“逆鄰接表”(存指向自己的邊)來方便計算“入度”
  • 不能檢查任意一對頂點間是否存在邊