Go常用算法集锦

news2024/11/26 4:27:36

前言

在日常开发中,我们经常会遇到一些针对复杂数据的处理,这时我们就会针对不同的业务使用不同算法,减少代码的逻辑复杂度,增加项目的可维护性,而为了保障项目的可持续性,一般都会进行算法的封装,当需要使用时,直接调用即可,这里为大家介绍一些常用的基础算法,以供各位大家参考,若有不对或者遗漏之处,欢迎评论区指出。

常用算法集锦

当然,为了更深入地理解深度优先搜索(DFS)和广度优先搜索(BFS),我们可以从基本概念出发,然后通过一个具体的图搜索问题来展示这两种算法的实现。

基本概念

在Go语言中,实现常用算法可以帮助你更好地理解编程逻辑和数据结构。以下是一些常用算法的示例,包括它们的实现过程和代码示例:

  1. 斐波那契数列

    • 描述:斐波那契数列是一系列数字,其中每个数字是前两个数字的和。
    • 实现:可以使用递归或迭代方法实现。
    • 代码示例(迭代):
      func fibonacci(n int) int {
          if n <= 1 {
              return n
          }
          a, b := 0, 1
          for i := 2; i <= n; i++ {
              a, b = b, a+b
          }
          return b
      }
      
  2. 二分查找
    在这里插入图片描述

    • 描述:在有序数组中查找某个目标值的位置。
    • 实现:通过每次将查找范围缩小一半来查找目标值。
    • 代码示例:
      func binarySearch(arr []int, target int) int {
          left, right := 0, len(arr)-1
          for left <= right {
              mid := left + (right-left)/2
              if arr[mid] == target {
                  return mid
              } else if arr[mid] < target {
                  left = mid + 1
              } else {
                  right = mid - 1
              }
          }
          return -1
      }
      
  3. 冒泡排序

    • 描述:通过重复遍历数组,比较并交换相邻元素来排序。
    • 实现:每次遍历都将最大的元素“冒泡”到末尾。
    • 代码示例:
      func bubbleSort(arr []int) {
          n := len(arr)
          for i := 0; i < n-1; i++ {
              for j := 0; j < n-i-1; j++ {
                  if arr[j] > arr[j+1] {
                      arr[j], arr[j+1] = arr[j+1], arr[j]
                  }
              }
          }
      }
      
  4. 递归算法

    • 描述:通过函数自己调用自己来解决问题。
    • 实现:定义一个函数,在其内部调用自己。
    • 代码示例(计算阶乘):
      func factorial(n int) int {
          if n == 0 {
              return 1
          }
          return n * factorial(n-1)
      }
      
  5. 快速排序

    • 描述:一种分治法策略的排序算法,通过选择一个“基准”元素,将数组分为两个子数组。
    • 实现:递归地对子数组进行快速排序。
    • 代码示例:
      func quickSort(arr []int) {
          if len(arr) < 2 {
              return
          }
          left, right := 0, len(arr)-1
          for left < right {
              for left < right && arr[right] >= arr[0] {
                  right--
              }
              arr[left], arr[right] = arr[right], arr[left]
              for left < right && arr[left] <= arr[0] {
                  left++
              }
              arr[left], arr[right] = arr[right], arr[left]
          }
          arr[left], arr[0] = arr[0], arr[left]
          quickSort(arr[:left])
          quickSort(arr[left+1:])
      }
      
  6. 归并排序

    • 描述:将两个已排序的数组合并成一个更大的已排序数组。
    • 实现:递归地将数组分成更小的数组,直到每个数组只有一个元素,然后合并它们。
    • 代码示例:
      func mergeSort(arr []int) []int {
          if len(arr) < 2 {
              return arr
          }
          mid := len(arr) / 2
          left := mergeSort(arr[:mid])
          right := mergeSort(arr[mid:])
      
          var i, j int
          var result []int
          for i < len(left) && j < len(right) {
              if left[i] <= right[j] {
                  result = append(result, left[i])
                  i++
              } else {
                  result = append(result, right[j])
                  j++
              }
          }
          return append(append(result, left[i:]...), right[j:]...)
      }
      
  7. 深度优先搜索(DFS)

    • 描述:用于遍历或搜索树或图的算法。
    • 实现:从一个节点开始,尽可能深地搜索树的分支。
    • 代码示例(图的DFS):
      func dfs(graph map[int][]int, visited map[int]bool, node int) {
          visited[node] = true
          for _, neighbor := range graph[node] {
              if !visited[neighbor] {
                  dfs(graph, visited, neighbor)
              }
          }
      }
      
  8. 广度优先搜索(BFS)

    • 描述:从最近的节点开始,逐层遍历图的算法。
    • 实现:使用队列来存储每一层的节点。
    • 代码示例(图的BFS):
      func bfs(graph map[int][]int, start int) {
          visited := make(map[int]bool)
          queue := []int{start}
          visited[start] = true
      
          for len(queue) > 0 {
              current := queue[0]
              queue = queue[1:]
              for _, neighbor := range graph[current] {
                  if !visited[neighbor] {
                      visited[neighbor] = true
                      queue = append(queue, neighbor)
                  }
              }
          }
      }
      
  9. 动态规划

    • 描述:通过将复杂问题分解成更简单的子问题来解决。
    • 实现:存储子问题的解,避免重复计算。
    • 代码示例(0-1背包问题):
      func knapsack(W int, wt []int, val []int, n int) int {
          K := make([][]int, n+1)
          for i := range K {
              K[i] = make([]int, W+1)
          }
      
          for i := 0; i <= n; i++ {
              for w := 0; w <= W; w++ {
                  if i == 0 || w == 0 {
                      K[i][w] = 0
                  } else if wt[i-1] <= w {
                      K[i][w] = max(val[i-1]+K[i-1][w-wt[i-1]], K[i-1][w])
                  } else {
                      K[i][w] = K[i-1][w]
                  }
              }
          }
          return K[n][W]
      }
      
  10. 图的最小生成树(Prim算法)

    • 描述:在图的边权重的条件下,构造一棵权重最小的生成树。
    • 实现:从一个节点开始,逐步添加最小权重的边。
    • 代码示例:
      func prim(graph [][]int) []int {
          n := len(graph)
          visited := make([]bool, n)
          edges := make([][]int, n)
          for i := range edges {
              edges[i] = []int{math.MaxInt32, i}
          }
          edges[0][0] = 0
      
          for i := 0; i < n; i++ {
              min := math.MaxInt32
              u := 0
              for j, visitedNode := range visited {
                  if edges[j][0] < min && !visitedNode {
                      min = edges[j][0]
                      u = j
                  }
              }
      
              visited[u] = true
              for v := 0; v < n; v++ {
                  if graph[u][v] > 0 && !visited[v] && graph[u][v] < edges[v][0] {
                      edges[v] = []int{graph[u][v], v}
                  }
              }
          }
      
          result := 0
          for _, edge := range edges {
              result += edge[0]
          }
          return result
      }
      
  11. 迪杰斯特拉算法(Dijkstra)

    • 描述:计算图中单个源点到其他所有顶点的最短路径。
    • 实现:使用优先队列和最小距离数组。
    • 代码示例:
      func dijkstra(graph [][]int, src int) []int {
          rows := len(graph)
          dist := make([]int, rows)
          for i := range dist {
              dist[i] = math.MaxInt32
          }
          dist[src] = 0
          visited := make([]bool, rows)
      
          for i := 0; i < rows; i++ {
              min := math.MaxInt32
              u := 0
              for j, v := range visited {
                  if !v && dist[j] < min {
                      min = dist[j]
                      u = j
                  }
              }
      
      visited[u] = true
              for v := 0; v < rows; v++ {
                  if !visited[v] && graph[u][v] > 0 && dist[u]+graph[u][v] < dist[v] {
                      dist[v] = dist[u] + graph[u][v]
                  }
              }
          }
          return dist
      }
      
  12. 字符串匹配算法(KMP算法)

    • 描述:在文本主串中搜索一个模式字符串的出现。
    • 实现:通过预处理模式字符串构建部分匹配表(PI表),提高搜索效率。
    • 代码示例:
      func KMPSearch(pat string, txt string) int {
          M := len(pat)
          N := len(txt)
          pi := computeLPSArray(pat, M)
          i := 0 // index for txt
          j := 0 // index for pat
          for i < N {
              if pat[j] == txt[i] {
                  i++
                  j++
              }
              if j == M {
                  return i - j
              } else if i < N && pat[j] != txt[i] {
                  if j != 0 {
                      j = pi[j-1]
                  } else {
                      i++
                  }
              }
          }
          return -1
      }
      
      func computeLPSArray(pat string, M int) []int {
          lps := make([]int, M)
          length := 0
          lps[0] = 0
          i := 1
          while i < M {
              if pat[i] == pat[length] {
                  length++
                  lps[i] = length
                  i++
              } else {
                  if length != 0 {
                      length = lps[length-1]
                  } else {
                      lps[i] = 0
                      i++
                  }
              }
          }
          return lps
      }
      

这些算法在Go语言中的实现只是基本示例,实际应用中可能需要根据具体情况进行调整和优化。

  1. 选择排序(Selection Sort)
  • 工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
package main

import "fmt"

// selectionSort 对切片进行选择排序
func selectionSort(arr []int) {
    n := len(arr)
    for i := 0; i < n-1; i++ {
        // 假设当前位置i是最小的索引
        minIndex := i
        // 遍历未排序的元素,找到最小值的索引
        for j := i + 1; j < n; j++ {
            if arr[j] < arr[minIndex] {
                minIndex = j
            }
        }
        // 如果最小值不是当前位置,则交换它们
        if minIndex != i {
            arr[i], arr[minIndex] = arr[minIndex], arr[i]
        }
    }
}

func main() {
    arr := []int{64, 25, 12, 22, 11}
    fmt.Println("Original array:", arr)
    selectionSort(arr)
    fmt.Println("Sorted array:  ", arr)
}

详细了解一下DFS、BFS以及链表

  1. 链表(LinkedList)
    首先,我们定义一个简单的单向链表节点和链表结构。
package main

import "fmt"

// ListNode 定义链表节点
type ListNode struct {
    Val  int
    Next *ListNode
}

// LinkedList 定义链表
type LinkedList struct {
    Head *ListNode
}

// Append 向链表末尾添加元素
func (l *LinkedList) Append(val int) {
    newNode := &ListNode{Val: val}
    if l.Head == nil {
        l.Head = newNode
    } else {
        current := l.Head
        for current.Next != nil {
            current = current.Next
        }
        current.Next = newNode
    }
}

// Print 打印链表
func (l *LinkedList) Print() {
    current := l.Head
    for current != nil {
        fmt.Print(current.Val, " ")
        current = current.Next
    }
    fmt.Println()
}

func main() {
    ll := &LinkedList{}
    ll.Append(1)
    ll.Append(2)
    ll.Append(3)
    ll.Print() // 输出: 1 2 3
}
  1. 深度优先搜索(DFS)

是一种用于遍历或搜索树或图的算法。它沿着树的深度遍历树的节点,尽可能深地搜索树的分支。在图中,这意味着尽可能深地探索从当前节点开始的路径,直到达到图的末端(即没有更多的邻居节点可以访问),然后回溯到上一个节点并尝试其他路径。

package main

import "fmt"

// Graph 以邻接表形式表示图
type Graph map[int][]int

// DFS 深度优先搜索
func DFS(graph Graph, start int, visited map[int]bool) {
    visited[start] = true
    fmt.Print(start, " ")
    for _, neighbor := range graph[start] {
        if !visited[neighbor] {
            DFS(graph, neighbor, visited)
        }
    }
}

func main() {
    graph := Graph{
        0: []int{1, 2},
        1: []int{2},
        2: []int{0, 3},
        3: []int{3},
    }
    visited := make(map[int]bool)
    DFS(graph, 0, visited) // 输出可能包括: 0 1 2 3(具体顺序取决于递归调用的栈)
}
  1. 广度优先搜索(BFS)

是另一种用于遍历或搜索树或图的算法。它从根节点开始,探索所有相邻的节点,然后再对每个相邻节点执行相同的操作,即先访问最近的节点,然后逐渐向外层扩展。在图中,这通常通过维护一个队列来实现,队列中保存了待访问的节点。。

package main

import (
    "container/list"
    "fmt"
)

// BFS 广度优先搜索
func BFS(graph Graph, start int) {
    visited := make(map[int]bool)
    queue := list.New()
    queue.PushBack(start)
    visited[start] = true

    for queue.Len() > 0 {
        front := queue.Remove(queue.Front()).(int)
        fmt.Print(front, " ")

        for _, neighbor := range graph[front] {
            if !visited[neighbor] {
                queue.PushBack(neighbor)
                visited[neighbor] = true
            }
        }
    }
}

func main() {
    graph := Graph{
        0: []int{1, 2},
        1: []int{2},
        2: []int{0, 3},
        3: []int{3},
    }
    BFS(graph, 0) // 输出: 0 1 2 3(具体顺序取决于队列的FIFO特性)
}

以上代码分别实现了链表的基本操作、图的深度优先搜索和广度优先搜索。这些是实现图论算法和数据结构操作的基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2124804.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

适配器模式详解和源码中应用

适配器模式 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它的作用是将一个类的接口转换为客户端所期望的另一种接口。适配器模式让原本接口不兼容的类能够合作无间&#xff0c;常用于将新系统集成到旧系统中。 形象的例子&#xff1a…

文心快码前端工程师观点分享:如何保证在企业内落地?

&#x1f381;&#x1f449;点击进入文心快码 Baidu Comate 官网&#xff0c;体验智能编码之旅&#xff0c;还有超多福利&#xff01;&#x1f381; 本系列视频来自百度工程效能部的前端研发经理杨经纬&#xff0c;她在由开源中国主办的“AI编程革新研发效能”OSC源创会杭州站1…

【3.3 激活函数(下)】

3.3 激活函数&#xff08;下&#xff09; 深度学习中的激活函数 在深度学习中&#xff0c;激活函数扮演着至关重要的角色&#xff0c;它们为神经网络引入了非线性特性&#xff0c;从而增强了模型的表达能力。以下是几种常见的激活函数及其简介、代码实现、优缺点等详细介绍。 …

深入理解AI Agent架构,史上最全解析!赶紧码住!

AI Agent框架&#xff08;LLM Agent&#xff09;&#xff1a;LLM驱动的智能体如何引领行业变革&#xff0c;应用探索与未来展望 1. AI Agent&#xff08;LLM Agent&#xff09;介绍 1.1. 术语 Agent&#xff1a;“代理” 通常是指有意行动的表现。在哲学领域&#xff0c;Agen…

计算机网络 ---- 电路交换、报文交换、分组交换

目录 零、前言 一、计算机网络发展初期面临的问题 1.1 电路交换的主要特点【电话网络采用电路交换技术】 1.1.1 电路交换的基本知识介绍 1.1.2 电路交换的优缺点 1.3 报文交换技术的特点【电报网络采用报文交换技术】 1.3.1 报文交换的基本知识介绍 1.3.2 报文交换技术…

中国企业500强!最新名单揭晓→

9月11日&#xff0c;在2024中国500强企业高峰论坛上&#xff0c;中国企业联合会、中国企业家协会连续第23次向社会发布了“中国企业500强”榜单。 01 营收规模迈上新台阶 2024中国企业500强营业收入迈上新台阶&#xff0c;突破了110万亿元大关&#xff0c;达110.07万亿元&…

【算法】哈希表相关

【ps】本篇有 5 道 leetcode OJ。 一、算法简介 哈希表是一种存储数据的容器&#xff0c;可以快速查找某个元素&#xff0c;其查找的时间复杂度为 O(1)&#xff0c;非常合适需要频繁查找某一个元素的场景。其具体用法为&#xff1a; 直接使用底层为哈希表的 STL 容器。用数组…

【一起学Rust | 进阶篇】使用Bon快速生成builder,提高代码质量

文章目录 前言一、安装Bon二、使用步骤1.为方法实现builder2.实现关联方法的builder3. 为结构体实现builder4. Option<T>字段成为可选项5. 实现Into转化 参考文档 前言 在 Rust 编程语言中&#xff0c;除了广为人知的单例模式之外&#xff0c;工厂模式也是极为容易见到的…

智能制造云平台---附源码79117

目 录 摘要 1 绪论 1.1 研究背景和意义 1.2开发技术 1.2.1 Flask框架 1.2.2 Python简介 1.2.3 MySQL数据库 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2总体设计原则 2.3 系统流程分析 2.3.1 用户登录流程 2.3.2 删除信息流程 2.4 系统角色分析 2.5 系…

微信小程序 - 最新将页面可分享到朋友圈功能,小程序实现分享到朋友圈功能,开启分享给好友及分享朋友圈功能(微信小程序怎么分享到朋友圈?详细流程及示例代码教程)

前言 没有设置过分享朋友圈功能的小程序,分享朋友圈按钮是灰色且无法点击。 在微信小程序开发中,详解实现把页面开启朋友圈分享功能,解决 “当前页面未设置分享” 且灰色无法点击问题,微信小程序开发中的微信分享和朋友圈分享设置,提供详细代码。 小程序 vue2 | vue3 版本…

yum下载软件失败:‘Could not resolve host: mirrorlist .centos .org; Unknowm error

Loaded plugins: fastestmirror, ovl Determining fastest mirrors Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7&archx86_64&repoos&infracontainer error was 14: curl#6 - “Could not resolve host: mirrorlist.centos.org; Unknow…

Games101图形学学习笔记——图形学基础

这里写目录标题 图形学基础线性代数Vector向量向量的点乘向量的叉乘 矩阵 Transform3D变换视图/相机变换 正交投影和透视投影正交投影透视投影 图形学基础 基础数学&#xff1a;线性代数&#xff0c;几何 基础物理&#xff1a;力学&#xff0c;光学 其他&#xff1a;信号处理&…

代码随想录训练营 Day56打卡 图论part06 108. 冗余连接 109. 冗余连接II

代码随想录训练营 Day56打卡 图论part06 一、卡码108. 冗余连接 题目描述 有一个图&#xff0c;它是一棵树&#xff0c;他是拥有 n 个节点&#xff08;节点编号1到n&#xff09;和 n - 1 条边的连通无环无向图&#xff08;其实就是一个线形图&#xff09;&#xff0c;如图&…

Java面试篇基础部分-Java的类加载机制

JVM的类加载 JVM在运行Java文件的时候,类加载分为5个阶段:加载、验证、准备、解析、初始化。在类初始化加载完成之后,就可以使用这个类的信息了。当这个类不需要使用的时候,就可以从JVM进行卸载。 加载 加载是指JVM读取Class文件的操作,并且根据Class的文件描述创建对应的…

工厂安灯系统在优化生产流程上的优势丨深圳讯鹏科技

工厂安灯系统通过可视化的方式&#xff0c;帮助工厂管理者和操作工人及时了解生产状态&#xff0c;快速响应问题&#xff0c;从而优化生产流程。 一、安灯系统实时监控与反馈 安灯系统的核心功能是实时监控生产线的状态。通过在生产现场设置灯光、显示屏等设备&#xff0c;工人…

单片机拍照_将采集的RGB图像封装为BMP格式保存到SD卡

文章目录 一、前言二、BMP文件结构2.1 BMP图片的格式说明 2.2 RGB888与RGB565格式是什么&#xff1f;&#xff08;1&#xff09;RGB565&#xff08;2&#xff09;RGB888&#xff08;3&#xff09;区别&#xff08;4&#xff09;如何构成&#xff08;5&#xff09;示例 三、实现…

yolo训练出现Could not load library libcudnn_cnn_train.so.8问题及解决方法

问题场景&#xff1a; 训练yolov5或者yolov8时候会报错&#xff1a; Could not load library libcudnn_cnn_train.so.8. Error: /usr/local/cuda-12.1/lib64/libcudnn_cnn_train.so.8: uined symbol: _ZN5cudnn3cnn34layerNormFwd_execute_internal_implERKNS_7backend11Vari…

【EasyExcel】@ColumnWidth(value = 20) EasyExcel设置列宽不生效

经过测试发现&#xff0c;只有XLS&#xff0c;ColumnWidth注解才会生效&#xff0c;选择CSV和XLSX都不会生效 //对应的导出实体类 EasyExcel.write(outputStream, Result.class)//excel文件类型&#xff0c;包括CSV、XLS、XLSX.excelType(ExcelTypeEnum.XLS)

当你学会了Python,随手爬取电影榜单!

一、爬电影TOP250 python爬取电影TOP250数据&#xff01; 首先&#xff0c;打开电影TOP250的页面&#xff1a; https://movie.douban.com/top250 开发好python代码后&#xff0c;成功后的csv数据&#xff0c;如下&#xff1a; 代码是怎样实现的爬取呢&#xff1f;下面逐一讲…

计算机网络相关概念

名词解释&#xff1a; 1.ARPANET ARPANET&#xff08;Advanced Research Projects Agency Network&#xff09;是由美国国防部高级研究计划局&#xff08;ARPA&#xff09;在1969年启动的一个实验性计算机网络项目。它是世界上第一个分组交换网络&#xff0c;也是互联网的前身…