hello-algo/codes/go/chapter_graph/graph_adjacency_list.go
Reanon 93ca29ca6d
feat(graph): add go codes (#314)
* feat(graph): add go codes

* feat(go/graph): add graph_adjacency_list

* doc(graph): add go codes

* fix(graph): fix go codes

* Update graph_adjacency_matrix_test.go

---------

Co-authored-by: Yudong Jin <krahets@163.com>
2023-02-05 16:08:08 +08:00

111 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// File: graph_adjacency_list.go
// Created Time: 2023-01-31
// Author: Reanon (793584285@qq.com)
package chapter_graph
import (
"fmt"
"strconv"
"strings"
)
/* 顶点类 */
type vertex struct {
val int
}
func newVertex(val int) vertex {
return vertex{
val: val,
}
}
/* 基于邻接表实现的无向图类 */
type graphAdjList struct {
// 请注意vertices 和 adjList 中存储的都是 Vertex 对象
// 邻接表(使用哈希表实现), 使用哈希表模拟集合
adjList map[vertex]map[vertex]struct{}
}
/* 构造函数 */
func newGraphAdjList(edges [][]vertex) *graphAdjList {
g := &graphAdjList{
adjList: make(map[vertex]map[vertex]struct{}),
}
// 添加所有顶点和边
for _, edge := range edges {
g.addVertex(edge[0])
g.addVertex(edge[1])
g.addEdge(edge[0], edge[1])
}
return g
}
/* 获取顶点数量 */
func (g *graphAdjList) size() int {
return len(g.adjList)
}
/* 添加边 */
func (g *graphAdjList) addEdge(vet1 vertex, vet2 vertex) {
_, ok1 := g.adjList[vet1]
_, ok2 := g.adjList[vet2]
if !ok1 || !ok2 || vet1 == vet2 {
panic("error")
}
// 添加边 vet1 - vet2, 添加匿名 struct{},
g.adjList[vet1][vet2] = struct{}{}
g.adjList[vet2][vet1] = struct{}{}
}
/* 删除边 */
func (g *graphAdjList) removeEdge(vet1 vertex, vet2 vertex) {
_, ok1 := g.adjList[vet1]
_, ok2 := g.adjList[vet2]
if !ok1 || !ok2 || vet1 == vet2 {
panic("error")
}
// 删除边 vet1 - vet2, 借助 delete 来删除 map 中的键
delete(g.adjList[vet1], vet2)
delete(g.adjList[vet2], vet1)
}
/* 添加顶点 */
func (g *graphAdjList) addVertex(vet vertex) {
_, ok := g.adjList[vet]
if ok {
return
}
// 在邻接表中添加一个新链表(即 set
g.adjList[vet] = make(map[vertex]struct{})
}
/* 删除顶点 */
func (g *graphAdjList) removeVertex(vet vertex) {
_, ok := g.adjList[vet]
if !ok {
panic("error")
}
// 在邻接表中删除顶点 vet 对应的链表
delete(g.adjList, vet)
// 遍历其它顶点的链表(即 Set删除所有包含 vet 的边
for _, set := range g.adjList {
// 操作
delete(set, vet)
}
}
/* 打印邻接表 */
func (g *graphAdjList) print() {
var builder strings.Builder
fmt.Printf("邻接表 = \n")
for k, v := range g.adjList {
builder.WriteString("\t\t" + strconv.Itoa(k.val) + ": ")
for vet := range v {
builder.WriteString(strconv.Itoa(vet.val) + " ")
}
fmt.Println(builder.String())
builder.Reset()
}
}