---
# System prepended metadata

title: 圖論基礎觀念

---

# 圖論基礎觀念
> 上一篇文章　[前綴和](https://hackmd.io/Dev0QF2US2a29hTVH3HdpA)
> 下一篇文章　[生成最小樹](/7isAK0zGTFeWEBy52goe2w)
> 先備知識　　無
> 延伸閱讀　　無
---
## 前言
圖論(Graph Theory)是探討關於「圖(Graph)」這個數學模型的理論。只要能將問題套用到graph上，就有方法可以解決這個問題。
## Graph基本觀念
Graph 是由節點（Vertex，有時也稱 Node）和邊（Edge）構成。
>`Vertex` : 承載資料
>`Edge` : 表達這些資料或對象間的關係
如果將Graph畫出來，vertex通常被畫成一個點，而edge就是線，將一個個節點(vertex)連起來。
例圖如下:![螢幕擷取畫面 2025-03-20 012951](https://hackmd.io/_uploads/S1UX1K_hye.png)
其實看起來有點像心智圖，生活中也有很多類似的例子，像是族譜、人物關係圖或是捷運路線圖等等。

## Graph的種類
### ==帶權圖（Weighted Graph）與無權圖（Unweighted Graph）==
>依照Edge是否帶有額外資訊決定，例如在捷運圖中站點之間所花時間之類的。
>這些額外的因素我們稱為==權重(Weight)==
>可以將Weight寫在Edge上
>如下圖片所示:
>![螢幕擷取畫面 2025-03-23 154603](https://hackmd.io/_uploads/HkpSh4621x.png)

:::info 
Edge 是否有方向性，以及 Edge 是否帶權，是個別獨立的，這些特性可以重複。
:::


### ==無向圖(Undirected Grapg)==
>無向圖的邊(Edge)為無向邊，可以表示為$(u, v)$代表$u$到$v$之間的邊，==可以相互往來==。
如例圖所示:
![螢幕擷取畫面 2025-03-21 234456](https://hackmd.io/_uploads/Byystbohkl.png)
以下還有一些例子:

| Graph | V(G~i~) | E(G~i~) |
| -------- | -------- | -------- |
| G~1~|{0,1,2,3}| {(0,1),(0,2),(0,3),(1,2),(1,3),(2,3)}|

>如果將資訊畫成圖就會像下圖所示:
![螢幕擷取畫面 2025-03-22 005534](https://hackmd.io/_uploads/HyLf5Mi21x.png)


### ==有向圖(Directed Graph)==
>有向圖的邊(Edge)為有向邊，可以表示為$<u, v>$代表從$u$到$v$的邊，不能相互往來，==只能從$u$到$v$，$v$不能到$u$==。
如例圖所示:
>![螢幕擷取畫面 2025-03-21 234950](https://hackmd.io/_uploads/B1gG3cbihkl.png)
>以下還有一些例子:

| Graph | V(G~i~) | E(G~i~) |
| -------- | -------- | -------- |
| G~2~|{0,1,2}| {<0,1>,<1,0>,<1,2>}|

>如果將資訊畫成圖就會像下圖所示:
>![螢幕擷取畫面 2025-03-22 010354](https://hackmd.io/_uploads/rJidhzs3ke.png)

## Graph的儲存方式
既然我們已經知道圖的基本概念了，接下來就要知道圖是如何儲存在程式碼中的。
常見的圖的儲存方式有兩種 `鄰接矩陣` 以及 `鄰接串列` 都是用Python中的List去存資料。

### ==鄰接矩陣 (Adjacency Matrix)==
>使用一個二維陣列存節點之間的關係，有點像表格。
>假設有$N$個節點，那就需要一個$N*N$的矩陣
>矩陣的index代表節點編號，如果今天存在$u$→$v$的邊，則$G$[$u$][$v$] = 1，否則就$G$[$u$][$v$] = 0。
>![螢幕擷取畫面 2025-03-22 170729](https://hackmd.io/_uploads/By6kReh2Jg.png)
>以上面這個無向圖作為範例，我們需要一個$4*4$的矩陣

>**範例程式碼**
> ```python=
> # Python
> # 範例：有 4 個節點的無向圖
> Graph = [
>     [0, 1, 1, 0],  # node 0 連到 1 跟 2 
>     [1, 0, 0, 1],  # node 1 連到 0 跟 3
>     [1, 0, 0, 1],  # node 2 連到 0 跟 3
>     [0, 1, 1, 0],  # node 3 連到 1 跟 2
> ]
> ```
> :::success
> 優點:直覺簡單
> :::
> :::danger
> 缺點:空間浪費
> :::

### ==鄰接串列 (Adjacency List)==
>也是用二維陣列去存節點之間的關係，但與前面不同，一個$N$個節點的圖不需要一個$N*N$的矩陣去存取它。
>Adjacency List中每個index對應一個節點，裡面放它連出去的節點
>![螢幕擷取畫面 2025-03-22 170729](https://hackmd.io/_uploads/HkarN-3nJe.png)
>一樣以上圖為例
>>**範例程式碼**
> ```python=
> # Python
> # 範例：有 4 個節點的無向圖
> Graph = [
>     [1, 2],  # node 0 連到 1 跟 2 
>     [0, 3],  # node 1 連到 0 跟 3
>     [0, 3],  # node 2 連到 0 跟 3
>     [1, 2],  # node 3 連到 1 跟 2
> ]
> ```
> :::success
> 優點:省空間
> :::
> 
> :::danger
> 缺點:查有沒有連邊要掃 list
> :::
> 
### ==如何存節點上的資料==
>看到這邊，你一定有疑問，上面教的儲存方式好像只能表示節點與節點之間的關係，啊我真正的資料要放哪裡?
>>**很簡單，通常會另外用個陣列或字典來對應節點資料**
>>
>下面用一個例子示範
> :::success
> 假設我們有 3 個節點，代表 3 個人，之間的Edge表示朋友關係：
> ![螢幕擷取畫面 2025-03-23 155726](https://hackmd.io/_uploads/SJGWJBahke.png)
>```python=
># Python
># 圖的 adjacency list
>graph = [
>    [1],     # 0 跟 1 連
>    [0, 2],  # 1 跟 0、2 連
>    [1]      # 2 跟 1 連
>]
>
># 節點的資料
>node_data = [
>    {"name": "阿明", "age": 25},
>    {"name": "小美", "age": 23},
>    {"name": "大雄", "age": 30}
>]
>
> ``` 
> :::
 
---
> 上一篇文章　[前綴和](https://hackmd.io/Dev0QF2US2a29hTVH3HdpA)
> 下一篇文章　[生成最小樹](/7isAK0zGTFeWEBy52goe2w)
> 先備知識　　無
> 延伸閱讀　　無











