Go语言常用算法实现

以下是Go语言中常用的算法实现,涵盖排序、搜索、数据结构操作等核心算法。

一、排序算法

1. 快速排序

Go 复制代码
func QuickSort(arr []int) []int {
    if len(arr) <= 1 {
        return arr
    }
    pivot := arr[0]
    var left, right []int
    for i := 1; i < len(arr); i++ {
        if arr[i] < pivot {
            left = append(left, arr[i])
        } else {
            right = append(right, arr[i])
        }
    }
    left = QuickSort(left)
    right = QuickSort(right)
    return append(append(left, pivot), right...)
}

2. 归并排序

Go 复制代码
func MergeSort(arr []int) []int {
    if len(arr) <= 1 {
        return arr
    }
    mid := len(arr) / 2
    left := MergeSort(arr[:mid])
    right := MergeSort(arr[mid:])
    return merge(left, right)
}

func merge(left, right []int) []int {
    result := make([]int, 0)
    for len(left) > 0 || len(right) > 0 {
        if len(left) == 0 {
            return append(result, right...)
        }
        if len(right) == 0 {
            return append(result, left...)
        }
        if left[0] <= right[0] {
            result = append(result, left[0])
            left = left[1:]
        } else {
            result = append(result, right[0])
            right = right[1:]
        }
    }
    return result
}

二、搜索算法

1. 二分查找

Go 复制代码
func BinarySearch(nums []int, target int) int {
    low, high := 0, len(nums)-1
    for low <= high {
        mid := low + (high-low)/2
        if nums[mid] == target {
            return mid
        } else if nums[mid] < target {
            low = mid + 1
        } else {
            high = mid - 1
        }
    }
    return -1
}

2. 广度优先搜索(BFS)

Go 复制代码
func BFS(graph map[int][]int, start int) []int {
    visited := make(map[int]bool)
    queue := []int{start}
    result := []int{}
    
    for len(queue) > 0 {
        node := queue[0]
        queue = queue[1:]
        
        if !visited[node] {
            visited[node] = true
            result = append(result, node)
            queue = append(queue, graph[node]...)
        }
    }
    return result
}

三、数据结构算法

1. 链表反转

Go 复制代码
type ListNode struct {
    Val  int
    Next *ListNode
}

func ReverseList(head *ListNode) *ListNode {
    var prev *ListNode
    current := head
    for current != nil {
        next := current.Next
        current.Next = prev
        prev = current
        current = next
    }
    return prev
}

2. 二叉树遍历

Go 复制代码
type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

// 前序遍历
func PreorderTraversal(root *TreeNode) []int {
    if root == nil {
        return nil
    }
    result := []int{root.Val}
    result = append(result, PreorderTraversal(root.Left)...)
    result = append(result, PreorderTraversal(root.Right)...)
    return result
}

四、动态规划

1. 斐波那契数列

Go 复制代码
func Fibonacci(n int) int {
    if n <= 1 {
        return n
    }
    dp := make([]int, n+1)
    dp[0], dp[1] = 0, 1
    for i := 2; i <= n; i++ {
        dp[i] = dp[i-1] + dp[i-2]
    }
    return dp[n]
}

// 空间优化版
func FibonacciOptimized(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. 最长公共子序列

Go 复制代码
func LongestCommonSubsequence(text1 string, text2 string) int {
    m, n := len(text1), len(text2)
    dp := make([][]int, m+1)
    for i := range dp {
        dp[i] = make([]int, n+1)
    }
    
    for i := 1; i <= m; i++ {
        for j := 1; j <= n; j++ {
            if text1[i-1] == text2[j-1] {
                dp[i][j] = dp[i-1][j-1] + 1
            } else {
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
            }
        }
    }
    return dp[m][n]
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

五、图算法

1. Dijkstra最短路径

Go 复制代码
func Dijkstra(graph map[int]map[int]int, start int) map[int]int {
    dist := make(map[int]int)
    for node := range graph {
        dist[node] = math.MaxInt32
    }
    dist[start] = 0
    
    pq := &PriorityQueue{}
    heap.Init(pq)
    heap.Push(pq, &Item{node: start, priority: 0})
    
    for pq.Len() > 0 {
        item := heap.Pop(pq).(*Item)
        u := item.node
        
        for v, weight := range graph[u] {
            if dist[v] > dist[u]+weight {
                dist[v] = dist[u] + weight
                heap.Push(pq, &Item{node: v, priority: dist[v]})
            }
        }
    }
    return dist
}

// 优先队列实现省略...

2. 拓扑排序

Go 复制代码
func TopologicalSort(graph map[int][]int) []int {
    inDegree := make(map[int]int)
    for u := range graph {
        inDegree[u] = 0
    }
    
    // 计算入度
    for _, neighbors := range graph {
        for _, v := range neighbors {
            inDegree[v]++
        }
    }
    
    queue := []int{}
    for u, degree := range inDegree {
        if degree == 0 {
            queue = append(queue, u)
        }
    }
    
    result := []int{}
    for len(queue) > 0 {
        u := queue[0]
        queue = queue[1:]
        result = append(result, u)
        
        for _, v := range graph[u] {
            inDegree[v]--
            if inDegree[v] == 0 {
                queue = append(queue, v)
            }
        }
    }
    
    if len(result) != len(graph) {
        return nil // 有环
    }
    return result
}

六、字符串算法

1. KMP字符串匹配

Go 复制代码
func KMP(text, pattern string) int {
    lps := computeLPS(pattern)
    i, j := 0, 0
    for i < len(text) {
        if pattern[j] == text[i] {
            i++
            j++
            if j == len(pattern) {
                return i - j
            }
        } else {
            if j != 0 {
                j = lps[j-1]
            } else {
                i++
            }
        }
    }
    return -1
}

func computeLPS(pattern string) []int {
    lps := make([]int, len(pattern))
    length := 0
    i := 1
    for i < len(pattern) {
        if pattern[i] == pattern[length] {
            length++
            lps[i] = length
            i++
        } else {
            if length != 0 {
                length = lps[length-1]
            } else {
                lps[i] = 0
                i++
            }
        }
    }
    return lps
}

2. Rabin-Karp字符串匹配

Go 复制代码
const primeRK = 16777619

func RabinKarp(text, pattern string) int {
    n := len(text)
    m := len(pattern)
    if n < m {
        return -1
    }
    
    hashPattern := hashStr(pattern)
    hashText := hashStr(text[:m])
    
    if hashText == hashPattern && text[:m] == pattern {
        return 0
    }
    
    pow := 1
    for i := 0; i < m-1; i++ {
        pow *= primeRK
    }
    
    for i := m; i < n; i++ {
        hashText = (hashText-int(text[i-m])*pow)*primeRK + int(text[i])
        if hashText == hashPattern && text[i-m+1:i+1] == pattern {
            return i - m + 1
        }
    }
    return -1
}

func hashStr(s string) int {
    h := 0
    for _, ch := range s {
        h = h*primeRK + int(ch)
    }
    return h
}

这些算法涵盖了Go语言开发中最常用的算法场景,建议结合实际需求进行优化和调整。

相关推荐
the sun344 分钟前
数据结构---跳表
数据结构
小黑屋的黑小子13 分钟前
【数据结构】反射、枚举以及lambda表达式
数据结构·面试·枚举·lambda表达式·反射机制
Go高并发架构_王工14 分钟前
基于 GoFrame 框架的电子邮件发送实践:优势、特色与经验分享
网络·经验分享·golang
LJianK115 分钟前
array和list在sql中的foreach写法
数据结构·sql·list
xiongmaodaxia_z719 分钟前
python每日一练
开发语言·python·算法
Chandler2433 分钟前
Go:接口
开发语言·后端·golang
ErizJ35 分钟前
Golang|Channel 相关用法理解
开发语言·后端·golang
automan0235 分钟前
golang 在windows 系统的交叉编译
开发语言·后端·golang
Pandaconda35 分钟前
【新人系列】Golang 入门(十三):结构体 - 下
后端·golang·go·方法·结构体·后端开发·值传递