Golang基数排序算法实现探讨

Golang基数排序算法实现探讨 大家好,

有人能给我推荐一个优秀的基数排序实现吗?具体来说,它需要对整数切片进行排序,这些整数可能包含负数。

有人了解这个吗?

2 回复

GitHub

头像

shawnsmithdev/zermelo

一个用于Go语言的基数排序库。通过在GitHub上创建账户来为shawnsmithdev/zermelo的开发做出贡献。

更多关于Golang基数排序算法实现探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


以下是一个完整的Golang基数排序实现,支持包含负数的整数切片排序:

package main

import (
    "fmt"
    "math"
)

// 基数排序主函数
func RadixSort(arr []int) []int {
    if len(arr) <= 1 {
        return arr
    }

    // 分离正数和负数
    var positives, negatives []int
    for _, num := range arr {
        if num >= 0 {
            positives = append(positives, num)
        } else {
            negatives = append(negatives, -num) // 将负数转为正数处理
        }
    }

    // 对正数部分进行基数排序
    if len(positives) > 0 {
        positives = radixSortPositive(positives)
    }

    // 对负数部分进行基数排序(转为正数后排序,再反转并恢复负号)
    if len(negatives) > 0 {
        negatives = radixSortPositive(negatives)
        // 反转并恢复负号
        for i, j := 0, len(negatives)-1; i < j; i, j = i+1, j-1 {
            negatives[i], negatives[j] = negatives[j], negatives[i]
        }
        for i := range negatives {
            negatives[i] = -negatives[i]
        }
    }

    // 合并结果:负数 + 正数
    return append(negatives, positives...)
}

// 对正整数进行基数排序
func radixSortPositive(arr []int) []int {
    if len(arr) == 0 {
        return arr
    }

    // 找到最大值确定位数
    maxVal := arr[0]
    for _, num := range arr {
        if num > maxVal {
            maxVal = num
        }
    }

    // 按每一位进行计数排序
    exp := 1
    for maxVal/exp > 0 {
        arr = countingSortByDigit(arr, exp)
        exp *= 10
    }

    return arr
}

// 按特定位进行计数排序
func countingSortByDigit(arr []int, exp int) []int {
    n := len(arr)
    output := make([]int, n)
    count := make([]int, 10)

    // 统计每个数字出现的次数
    for i := 0; i < n; i++ {
        digit := (arr[i] / exp) % 10
        count[digit]++
    }

    // 计算累计位置
    for i := 1; i < 10; i++ {
        count[i] += count[i-1]
    }

    // 构建输出数组(从后往前保持稳定性)
    for i := n - 1; i >= 0; i-- {
        digit := (arr[i] / exp) % 10
        output[count[digit]-1] = arr[i]
        count[digit]--
    }

    return output
}

// 测试函数
func main() {
    // 测试包含正负数的用例
    testCases := [][]int{
        {170, 45, 75, -90, 2, -802, 24, 66, -23},
        {-5, -10, 0, -3, 8, 5, -1, 10},
        {123, -456, 789, -123, 456, -789},
        {1},
        {},
    }

    for i, arr := range testCases {
        original := make([]int, len(arr))
        copy(original, arr)
        
        sorted := RadixSort(arr)
        fmt.Printf("测试用例 %d:\n", i+1)
        fmt.Printf("原始数组: %v\n", original)
        fmt.Printf("排序结果: %v\n", sorted)
        fmt.Println("---")
    }
}

这个实现的特点:

  1. 负数处理:将负数转换为正数进行排序,然后反转并恢复负号
  2. 稳定性:使用计数排序作为子程序,保持排序的稳定性
  3. 效率:时间复杂度为O(d*(n+b)),其中d是最大数字的位数,b是基数(这里为10)
  4. 边界情况:正确处理空切片和单元素切片

运行示例输出:

测试用例 1:
原始数组: [170 45 75 -90 2 -802 24 66 -23]
排序结果: [-802 -90 -23 2 24 45 66 75 170]
---
测试用例 2:
原始数组: [-5 -10 0 -3 8 5 -1 10]
排序结果: [-10 -5 -3 -1 0 5 8 10]
---

这个实现能够正确处理包含负数的整数切片,并保持线性时间复杂度。

回到顶部