Golang-图结构的实现

基本概念

图(Graph)是一种复杂的非线性结构,在图结构中,每个元素都可以有零个或多个前驱,也可以有零个或多个后继,也就是说,元素之间的关系是任意的。

常用术语

术语含义
顶点图中的某个结点
顶点之间连线
相邻顶点由同一条边连接在一起的顶点
一个顶点的相邻顶点个数
简单路径由一个顶点到另一个顶点的路线,且没有重复经过顶点
回路出发点和结束点都是同一个顶点
无向图图中所有的边都没有方向
有向图图中所有的边都有方向
无权图图中的边没有权重值
有权图图中的边带有一定的权重值

结构及实现

type Node struct {
	Value, In, Out int // 值,入度,出度
	Nexts          []*Node
	Edges          []*Edge
}

type Edge struct {
	Weight int
	From   *Node
	To     *Node
}

type Graph struct {
	Nodes map[int]*Node
	Edges map[*Edge]struct{}
}

// 从别的图结构转成自己的结构,可以根据适当减少字段如出入度,权重
func CreateGraph(matrix [][]int) Graph {
	graph := Graph{}
	for _, v := range matrix {
		weight := v[0]
		from := v[1]
		to := v[2]
		if _, ok := graph.Nodes[from]; !ok {
			graph.Nodes[from] = &Node{
				Value: from,
			}
		}
		if _, ok := graph.Nodes[to]; !ok {
			graph.Nodes[to] = &Node{
				Value: to,
			}
		}
		fromNode := graph.Nodes[from]
		toNode := graph.Nodes[to]
		edge := &Edge{
			Weight: weight,
			From:   fromNode,
			To:     toNode,
		}
		fromNode.Out++
		toNode.In++
		fromNode.Nexts = append(fromNode.Nexts, toNode)
		fromNode.Edges = append(fromNode.Edges, edge)
		graph.Edges[edge] = struct{}{}
	}
	return graph
}

图的深度优先遍历

从一个顶点开始,沿着一条路径一直搜索,直到到达该路径的最后一个结点,然后回退到之前经过但未搜索过的路径继续搜索,直到所有路径和结点都被搜索完毕

func GraphDFS(start *Node) {
	if start == nil {
		return
	}
	stack := stack.NewStack[*Node]()
	set := map[*Node]struct{}{}
	set[start] = struct{}{}
	stack.Push(start)
	fmt.Print(start.Value)
	for !stack.IsEmpty() {
		cur, _ := stack.Pop()
		for _, v := range cur.Nexts {
			if _, ok := set[v]; !ok {
				stack.Push(cur)
				stack.Push(v)
				fmt.Print(v.Value)
				set[v] = struct{}{}
				break
			}
		}
	}
}

图的广度优先遍历

类似于图的层次遍历,它的基本思想是:首先访问起始顶点v,然后选取v的所有邻接点进行访问,再依次对v的邻接点相邻接的所有点进行访问,以此类推,直到所有顶点都被访问过为止

func GraphBFS(start *Node) {
	if start == nil {
		return
	}
	queue := queue.NewQueue[*Node]()
	set := map[*Node]struct{}{}
	queue.Push(start)
	set[start] = struct{}{}
	for !queue.IsEmpty() {
		cur := queue.Pop()
		fmt.Print(cur.Value)
		for _, v := range cur.Nexts {
			if _, ok := set[v]; !ok {
				queue.Push(v)
				set[v] = struct{}{}
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值