Problem: You want to create a weighted graph data structure.
Solution: Create structs for nodes and edges and place them in a Graph struct. Create and attach functions to Graph to create nodes and edges for the graph.
Graphs are very common nonlinear data structures that are used everywhere to map relationships between entities. A graph consists of nodes and edges where edges connect two nodes and often represent the relationship between two nodes. Nodes are often given a name and sometimes a value.
You’ll implement a type of graph called the undirected weighted graph , where the edges are also associated with a value, and the edges connect the nodes both ways. As you probably realize, there are many other kinds of graphs, but you can use the same techniques to implement them.
Here are the basic functions of a graph:
AddNode
• Add a new node into the graph
AddEdge
• Add a new edge that connects two nodes
RemoveNode
• Remove an existing node from the graph
RemoveEdge
• Remove an existing edge from the graph
You will use three structs to implement the weighted graph. The Node struct represents a node, with a given name. The Edge struct has a pointer to a node and also a weight. It might look odd but there is a reason for this:
type Node struct { name string } type Edge struct { node *Node weight int } type Graph struct { Nodes []*Node Edges map[string][]*Edge // key is node name }
The last is the Graph struct, which represents the weighted graph. The Graph struct has a slice of pointers to Node structs. It also has a map that has a string key that associates with a slice of pointers to Edge structs. The key for this map is the name of the node and the value is a slice of Edge structs.
Edges are implemented using a map so you can’t create a new Graph struct without also initializing the Edges field. To do this you have a function to create a new Graph struct:
func NewGraph() *Graph { return &Graph{ Edges: make(map[string][]*Edge), } }
func (g *Graph) AddNode(n *Node) { g.Nodes = append(g.Nodes, n) } func (g *Graph) AddEdge(n1, n2 *Node, weight int) { g.Edges[n1.name] = append(g.Edges[n1.name], &Edge{n2, weight}) g.Edges[n2.name] = append(g.Edges[n2.name], &Edge{n1, weight}) } func (g *Graph) RemoveEdge(n1, n2 string) { removeEdge(g, n1, n2) removeEdge(g, n2, n1) } func removeEdge(g *Graph, m, n string) { edges := g.Edges[m] r := -1 for i, edge := range edges { if edge.node.name == n { r = i } } if r > -1 { edges[r] = edges[len(edges)-1] g.Edges[m] = edges[:len(edges)-1] } } func (g *Graph) RemoveNode(name string) { r := -1 for i, n := range g.Nodes { if n.name == name { r = i } } if r > -1 { g.Nodes[r] = g.Nodes[len(g.Nodes)-1] // remove the node g.Nodes = g.Nodes[:len(g.Nodes)-1] } delete(g.Edges, name) // remove the edge from one side // remove the edge from the other side for n := range g.Edges { removeEdge(g, n, name) } }
Removing an edge is a bit more involved. The edges are in a slice that are the values in the Edges map, so you need to iterate through them and mark it if it’s to be removed. Once you find out where the edge is, take the last element in the slice and place it at the index, effectively removing that edge. After that, reslice to truncate the last element. You have to do this twice to remove edges from both directions since this is an undirected graph.
Removing nodes is also a bit more involved but very much the same as removing edges. First, you need to find out the index of the node to remove. Once you do that you take the last element in the slice and place it at the index, then truncate the last element. You also need to remove the edges that are connected to the node. First, delete the edge from the Edges map. Then go through the rest of the other key-value pairs and remove the node accordingly.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律