用Golang编写深度优先搜索算法

用Golang编写深度优先搜索算法

在本文中,我们将学习如何使用内部Golang函数(如make、append和range)来实现深度优先搜索。深度优先搜索是用于图和树数据结构的遍历算法。它递归地探索图的所有节点。

语法

func make([]type, size, capacity)

在Go语言中,make函数用于创建一个数组/映射,它接受要创建的变量类型,其大小和容量作为参数。

func append(slice, element_1, element_2…, element_N) []T

append函数用于将值添加到数组切片中。它接受多个参数。第一个参数是我们希望将值添加到其中的数组,其后是要添加的值。然后该函数返回包含所有值的最终数组切片。

func range(variable)

range函数用于遍历任何数据类型。要使用它,我们首先需要写range关键字,后接我们想要遍历的数据类型,结果循环将迭代到变量的最后一个元素。

使用邻接表表示法

在这种方法中,我们将编写一个Golang程序,使用邻接表表示法来表示图并执行深度优先搜索。函数DFS和DFSUtil将用于执行深度优先搜索。

算法

  • 步骤1 − 在程序中导入fmt和main包,其中fmt帮助格式化输入和输出,而main确保程序应为可执行程序。

  • 步骤2 − 创建一个Graph结构,其中顶点的类型为int,邻接表表示将用于表示该图。

  • 步骤3 − 然后,创建一个AddEdge方法,其中源和目标作为输入,在其中从源到目标添加边。

  • 步骤4 − 创建一个方法DFS,startVertex作为输入。在该函数中,使用make函数初始化visited map,该函数是Golang中的内置函数。

  • 步骤5 − 从DFS中调用方法DFSUtil,其中包括两个输入:起始顶点和初始化的映射。

  • 步骤6 − 在以下函数中,递归访问顶点,一旦访问,将其设置为已访问的顶点,并使用来自fmt包的Println将其打印到控制台上,其中ln表示换行。

  • 步骤7 − 在main中,通过将顶点值传递给AddEdge函数,将顶点连接起来以形成边,从而创建图。

示例

下面的示例演示了使用邻接表表示法实现深度优先搜索的Golang程序。

包 main

import "fmt"

type Graph struct {   
   vertices int
   adjList  map[int][]int
}

func NewGraph(vertices int) *Graph {
   return &Graph{
      vertices: vertices,
      adjList:  make(map[int][]int),
   }
}

func (g *Graph) AddEdge(source, dest int) {
   g.adjList[source] = append(g.adjList[source], dest) 
   g.adjList[dest] = append(g.adjList[dest], source)
}

func (g *Graph) DFSUtil(vertex int, visited map[int]bool) {
   visited[vertex] = true
   fmt.Printf("%d ", vertex) 

   for _, v := range g.adjList[vertex] {
      if !visited[v] {
         g.DFSUtil(v, visited)
      }
   }
}

func (g *Graph) DFS(startVertex int) {
   visited := make(map[int]bool)
   g.DFSUtil(startVertex, visited)    
}

func main() {    
   g := NewGraph(5)   
   g.AddEdge(0, 1)
   g.AddEdge(0, 2)
   g.AddEdge(1, 3)
   g.AddEdge(1, 4)

   fmt.Println("从顶点0开始的深度优先遍历:")
   g.DFS(0)
}

输出

从顶点0开始的深度优先遍历:
0 1 3 4 2 

使用邻接矩阵表示进行迭代

在这种方法中,我们将编写Golang程序来使用迭代中的邻接矩阵表示实现深度优先搜索。在此方法中,将使用DFS和DFSUtil方法来执行深度优先搜索。

算法

  • 第一步 − 在程序中导入fmt和main程序包,其中fmt会帮助格式化输入和输出,而main则确保程序应该是可执行程序。

  • 第二步 − 创建一个Graph结构体来存储邻接矩阵表示,其中vertices的类型为int。

  • 第三步 − 创建一个AddEdge方法,将源和目的地作为参数传递进来。在此方法中,将从源到目的地添加边缘以创建图形。

  • 第四步 − 在这一步中,创建一个带startvertex输入的DFS方法。在此函数中,创建一个visited map,如果访问了特定顶点,则将其设置为true。

  • 第五步 − 然后,从这里调用带顶点和visited map作为参数的DFSUtil方法。

  • 第六步 − 递归地访问图形的每个顶点,打印它并在顶点被访问后将visited设置为true。

  • 第七步 − 在main中,提供AddEdge方法与要连接的顶点的输入参数组成部分来创建图形。

示例

以下示例显示了使用迭代中的邻接矩阵表示实现深度优先搜索的Golang程序。

package main

import "fmt"

type Graph struct {
   vertices  int
   adjMatrix [][]bool
}

func NewGraph(vertices int) *Graph {
   matrix := make([][]bool, vertices)
   for i := 0; i < vertices; i++ {
      matrix[i] = make([]bool, vertices)
   }
   return &Graph{
      vertices:  vertices,
      adjMatrix: matrix,
   }
}

func (g *Graph) AddEdge(source, dest int) { 
   g.adjMatrix[source][dest] = true
   g.adjMatrix[dest][source] = true
}

func (g *Graph) DFSUtil(vertex int, visited []bool) {
   visited[vertex] = true
   fmt.Printf("%d ", vertex)

   for i := 0; i < g.vertices; i++ {
      if g.adjMatrix[vertex][i] && !visited[i] {
         g.DFSUtil(i, visited)
      }
   }
}

func (g *Graph) DFS(startVertex int) {
   visited := make([]bool, g.vertices)
   g.DFSUtil(startVertex, visited)   
}

func main() {
   g := NewGraph(5)
   g.AddEdge(0, 1)    
   g.AddEdge(0, 2)
   g.AddEdge(1, 3)
   g.AddEdge(1, 4)

   fmt.Println("从顶点0开始的深度优先遍历:")
   g.DFS(0)
}

输出

从顶点0开始的深度优先遍历:
0 1 3 4 2

使用递归

在此方法中,我们将编写一个 Golang 程序,使用递归实现深度优先搜索。该函数将在节点未访问时被调用。

算法

  • 步骤 1 − 该程序导入主要包和 fmt 包。其中主要帮助生成可执行代码,并 fmt 帮助格式化输入和输出

  • 步骤 2 − 创建一个 Node 结构,具有三个字段:值(表示节点数据),类型为 bool 的 visited(确定节点是否已访问)

  • 步骤 3 − 最后一个是透过 edges 添加边

  • 步骤 4 − 创建一个函数 DFS,其将节点作为参数,即根节点

  • 步骤 5 − 检查根节点是否为空,如果为空,则返回

  • 步骤 6 − 然后,将根节点的访问设置为 true

  • 步骤 7 − 在控制台上打印节点值

  • 步骤 8 − 迭代节点边缘并检查边缘是否已访问

  • 步骤 9 − 如果边缘未被访问,则使用该边缘作为参数递归调用 DFS 函数

  • 步骤 10 − 在 main 函数中,设置节点值并连接节点创建边

  • 步骤 11 − 使用 node1 作为参数调用函数 DFS

  • 步骤 12 − 使用 fmt 包的 Printf 函数执行 Print 语句

示例

以下示例说明如何创建一个 Go 编程,使用递归实现深度优先搜索

package main

import "fmt"

type Node struct {
   value int
   visited bool
   edges []*Node
}

func DFS(node *Node) {
   if node == nil {
      return
    }

   node.visited = true
   fmt.Printf("%d ", node.value)

   for _, edge := range node.edges {
      if !edge.visited {
         DFS(edge)
      }
   }
}

func main() {
   node1 := &Node{value: 10}
   node2 := &Node{value: 20}
   node3 := &Node{value: 30}
   node4 := &Node{value: 40}
   node5 := &Node{value: 50}

   node1.edges = []*Node{node2, node3}
   node2.edges = []*Node{node4, node5}
   node3.edges = []*Node{node5}

   DFS(node1)
}

输出

DFS 遍历结果是:
10 20 40 50 30

结论

我们编译并执行了使用三个示例实现深度优先搜索的程序。在第一个示例中使用邻接表表示,在第二个示例中使用邻接矩阵表示,在第三个示例中使用递归。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程