美文网首页
golang 写个基数排序

golang 写个基数排序

作者: 追风骚年 | 来源:发表于2021-01-26 15:22 被阅读0次

在编写基数排序的时候,我还找到一个规律,取一个数的个位十位百位,是经常需要用到的

// 数字,右数第几位,从1开始
func digit(num int, loc int) int {
    return num % int(math.Pow10(loc)) / int(math.Pow10(loc-1))
}

算法描述

  • 取得数组中的最大数,并取得位数;
  • arr为原始数组,从最低位开始取每个位组成radix数组;
  • 对radix进行计数排序(利用计数排序适用于小范围数的特点);

算法实习

版本一

为了简单起见,我这里用了一个 数组,数组中是一个队列,这样可以方便取到队列头部数据。

func radixsort(arr []int) []int {
    maxValueLen := 0 // 需要循环多少次,以最大数字为准
    for i := 0; i < len(arr); i++ {
        n := len(strconv.Itoa(arr[i])) // 方便起见,数字转字符,再取长度
        if n > maxValueLen {
            maxValueLen = n
        }
    }

    for loc := 1; loc <= maxValueLen; loc++ {
        arr = sort(arr, loc)
    }
    return arr
}

// 数组中每一位都需要排序
func sort(arr []int, loc int) []int {
    bucket := make([]*list.List, 10) // 0~9 总共10个队列
    for i := 0; i <= 9; i++ {
        bucket[i] = list.New()
    }

    for i := 0; i < len(arr); i++ {
        ji := digit(arr[i], loc)    // 获取对应位的数字
        bucket[ji].PushBack(arr[i]) //按数字 将数据 push 进队列
    }

    tempArr := []int{}
    for i := 0; i <= 9; i++ {
        for bucket[i].Len() > 0 { // 队列中不为空
            fv := bucket[i].Front() // 将数据弹出
            tempArr = append(tempArr, fv.Value.(int))
            bucket[i].Remove(fv)
        }
    }
    return tempArr // 将本轮排好序的数据返回
}

// 数字,右数第几位,从1开始
func digit(num int, loc int) int {
    return num % int(math.Pow10(loc)) / int(math.Pow10(loc-1))
}

func TestRadixsort(t *testing.T) {
    arr := []int{1, 2, 12, 4343242, 123, 4, 55, 666, 77, 102, 3249, 21210, 31312}
    t.Log(arr)
    t.Log(radixsort(arr))
}

func BenchmarkRadixsort(b *testing.B) {
    arr := rand.Perm(math.MaxInt16 * 10)
    for i := 0; i < b.N; i++ {
        radixsort(arr)
    }
}

版本二


func radixsort(arr []int) []int {
    maxValueLen := 0 // 需要循环多少次,以最大数字为准
    for i := 0; i < len(arr); i++ {
        n := len(strconv.Itoa(arr[i])) // 方便起见,数字转字符,再取长度
        if n > maxValueLen {
            maxValueLen = n
        }
    }
    for loc := 1; loc <= maxValueLen; loc++ {
        sort(arr, loc)
    }
    return arr
}

func sort(arr []int, loc int) {
    bucket := make([][]int, 10) // 0~9 总共10个队列

    for i := 0; i < len(arr); i++ {
        ji := digit(arr[i], loc) // 获取对应位的数字
        if bucket[ji] == nil {
            bucket[ji] = make([]int, 0) // 如果 bucket 需要再去初始化
        }

        bucket[ji] = append(bucket[ji], arr[i]) // 将数字 push 进去
    }

    idx := 0
    for i := 0; i <= 9; i++ {
        for j := 0; j < len(bucket[i]); j++ {
            // 遍历二维数组
            arr[idx] = bucket[i][j] //将数字取出来 给原数组重新赋值
            idx++
        }
    }
}

// 数字,右数第几位,从1开始
func digit(num int, loc int) int {
    return num % int(math.Pow10(loc)) / int(math.Pow10(loc-1))
}

func TestRadixsort(t *testing.T) {
    arr := []int{1, 2, 12, 4343242, 123, 4, 55, 666, 77, 102, 3249, 21210, 31312}
    t.Log(arr)
    // t.Log(radixsort(arr))
    t.Log(radixsort(arr))
}


func BenchmarkRadixsort(b *testing.B) {
    arr := rand.Perm(math.MaxInt16 * 10)
    for i := 0; i < b.N; i++ {
        radixsort(arr)
    }
}


版本二直接使用了一个二维数组去实现了,后面直接去掉 tempArr,给原数组赋值即可,对各种写法都Benchmark了一下,确实性能提供了很多倍。

小结

基数排序的逻辑可以查看B站,但是他的代码,让我很费解,这边都是自己实现的逻辑,感觉比较好理解。

至此,8大排序均已写完,大学里用 c 和 java 都实现过,这是用 golang 重新实现了。知识这东西时间长了那真是叫似曾相识,理不清楚。

相关文章

  • golang 写个基数排序

    在编写基数排序的时候,我还找到一个规律,取一个数的个位十位百位,是经常需要用到的 算法描述 取得数组中的最大数,并...

  • golang 写个冒泡

    在算法这个领域,大学的课程也都是从冒泡排序开始的,今天用 golang 写个简单的冒泡排序。 这实在有点简单,特别...

  • golang + goquery写个爬虫

    goquery 是一个超好用的库,可以帮你爬取页面,解析页面。我用它写了个糗事百科的爬虫,可以用来看当前有什么好玩...

  • golang 写个堆排序

    堆排序是我觉得排序里面数据结构运用最灵活的一个算法,首先如何用一个数组表示一个堆,如何取到节点的父节点和左右子节点...

  • golang 写个希尔排序

    希尔排序非常的牛,听说是第一个打破时间复杂度我 n² 的算法,通过一个区间不断缩小,由远及近,最终达到有序状态,也...

  • golang 写个快速排序

    快速排序是大多数语言内置 sort 函数的默认实现方式,简单可分为两路排序和三路排序,我在相关资料中,发现两路排序...

  • golang 写个选择排序

    先看选择排序定义。 初始状态:无序区为R[1..n],有序区为空; 第i趟排序(i=1,2,3…n-1)开始时,当...

  • golang 写个归并排序

    归并排序是核心原理是分治和递归的运用,分治,那就需要分而治之,治在这里有治理合并意义。 算法描述 把长度为n的输入...

  • golang 写个插入排序

    有点上瘾,再来写一个。 从第一个元素开始,该元素可以认为已经被排序; 取出下一个元素,在已经排序的元素序列中从后向...

  • golang简单爬虫Demo

    看完golang的文档,写个爬虫练手,记录下学习过程。项目地址:https://github.com/gushas...

网友评论

      本文标题:golang 写个基数排序

      本文链接:https://www.haomeiwen.com/subject/cwdgzktx.html