網站首頁 編程語言 正文
圖的結構特點
圖由頂點和頂點之間的邊構成,記為G(V, E)。其中V是頂點集合,E是邊集合。作為一種非線性的數據結構,頂點之間存在多對多關系。
圖的分類
無向圖:兩個頂點之間有兩條互相關聯的邊。A和B之間為雙向互通。
有向圖:兩個頂點之間有一條或兩條關聯的邊。從A到B或者從B到A,只能單向通過。
帶權無向圖:在無向圖的基礎上增加一個權值,代表距離等衡量單位。
帶權有向圖:在有向圖的基礎上增加一個權值,代表距離等衡量單位。
圖的表示
圖的表示分為兩種方法:鄰接矩陣和鄰接表。
基于鄰接表的概念手動構建四種類型的圖,演示如下:
// 有向圖 let graph = { A: { B: null, C: null }, B: { C: null }, C: {}, } // 無向圖 let graph = { A: { B: null, C: null }, B: { A: null, C: null }, C: { A: null, B: null }, } // 帶權有向圖 let graph = { A: { B: 20, C: 20 }, B: { C: 40 }, C: {}, } // 帶權無向圖 let graph = { A: { B: 20, C: 30 }, B: { A: 20, C: 40 }, C: { A: 30, B: 40 }, }
面向對象方法封裝鄰接表
構造函數
class Graph { length: number vertices: { [key: string]: { [key: string]: null | number } } isDirected: boolean constructor(isDirected: boolean = false) { this.length = 0 this.vertices = {} this.isDirected = isDirected } }
增加頂點和邊
頂點增加:利用傳入key
參數在頂點集合新建一個屬性,值為一個空對象用于存儲邊。
addVertex(...vertices: string[]): Graph { vertices.forEach((key: string) => { this.vertices[key] = {} this.length++ }) return this }
邊增加需要處理的三種情況:
- 頂點不存在:執(zhí)行
addVertex
增加頂點。 - 有向圖:兩個頂點間建立一條關聯的邊。
- 無向圖:兩個頂點間建立互相關聯的兩條邊。
addEdge(v: string, edges: { [key: string]: null | number}): Graph { if (!this.vertices[v]) { this.addVertex(v) } for (const key in edges) { if (!this.vertices[key]) { this.addVertex(key) } this.vertices[v][key] = edges[key] if (!this.isDirected) { this.vertices[key][v] = edges[key] } } return this }
刪除頂點和邊
頂點刪除:需要刪除與這個頂點與其他頂點關聯的邊。
removeVertex(v: string): Graph { delete this.vertices[v] for (const key in this.vertices) { if (!!this.vertices[key][v]) { delete this.vertices[key][v] } } this.length-- return this }
邊刪除:有向圖,刪除一個頂點關聯的邊即可;無向圖,刪除兩條頂點互相關聯的邊。
removeEdge(v: string, w: string): Graph { delete this.vertices[v][w] if (!this.isDirected) { delete this.vertices[w][v] } return this }
圖的遍歷
顏色標記
為圖中的每一個頂點標記顏色,作為狀態(tài)記錄。三種顏色狀態(tài)分別如下:
- 白色:未發(fā)現的頂點
- 灰色:被發(fā)現的頂點
- 黑色:已遍歷過的頂點
// 初始化所有頂點顏色,作為初始的狀態(tài) const initColor = (vertices: { [key: string]: { [key: string]: null | number } }) : { [key: string]: 'white' | 'gray' | 'black' } => { let color = {} for (const key in vertices) { color[key] = 'white' } return color }
廣度優(yōu)先搜索(隊列)
實現思路:
- 初始化所有的頂點狀態(tài)為白色,選擇一個初始頂點入隊開始進行搜索。
- 當隊列不為空,被選中的初始頂點出隊。將這個頂點(通過邊)關聯的其他頂點入隊,并為其標記為灰色。
- 當執(zhí)行完第二步后,將初始頂點標記為黑色。然后第二步入隊的頂點都會重復二、三步驟直到隊列為空。
const breadthFirstSearch = (graph: Graph, startVertex: string): string[] => { let result: string[] = [] let v: string = startVertex const color = initColor(graph.vertices) const queue = new Queue() queue.enqueue(v) while (!queue.isEmpty()) { v = queue.dequeue() for (const key in graph.vertices[v]) { if (color[key] === 'white') { queue.enqueue(key) color[key] = 'gray' } } color[v] = 'black' result.push(v) } return result }
深度優(yōu)先搜索(棧)
實現思路:與廣度優(yōu)先搜索步驟相同,隊列換為棧即可。需要注意的是深度優(yōu)先搜索結果不唯一。
const depthFirstSearch = (graph: Graph, startVertex: string): string[] => { let result: string[] = [] let v: string = startVertex const color = initColor(graph.vertices) const stack = new Stack() stack.push(v) while (!stack.isEmpty()) { v = stack.pop() for (const key in graph.vertices[v]) { if (color[key] === 'white') { stack.push(key) color[key] = 'gray' } } color[v] = 'black' result.push(v) } return result }
本文相關代碼已放置我的Github倉庫 ?
項目地址:
Algorithmlib|Graph
Algorithmlib|Graph Traversal
原文鏈接:https://juejin.cn/post/7193720313635405881
相關推薦
- 2023-03-28 python數組如何添加整行或整列_python
- 2021-12-16 el-tree 設置選項框選中狀態(tài),通過setCheckedKeys設置,會導致父選項框選中,子選項
- 2023-07-08 keycloak更新token調用updateToken函數無效,解決辦法
- 2022-09-10 Oracle數據泵實現不同用戶導入導出表級_oracle
- 2023-06-03 React實現一個倒計時hook組件實戰(zhàn)示例_React
- 2022-01-06 node的淘寶鏡像下載路徑cnpm
- 2022-12-08 詳解C++引用變量時那些你不知道的東西_C 語言
- 2022-10-25 Go語言實戰(zhàn)學習之流程控制詳解_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支