学习回顾算法(基数排序算法)

基数排序概述

基数排序(radix sort)属于分配式排序,又称为“桶子法”(bucket sort)或bin sort。顾名思义,它是透过键值,把要排序的元素分配到已经排好优先级的“桶”中,以达到排序的作用。比如数字中0,1,2,3,4,5,6,7,8,9。就是已经排好序的桶了。在某些时候基数排序的效率高于其他排序算法。

基数排序算法原理

基数排序(以整形为例),将整形10进制按每位拆分,然后从低位到高位依次比较各个位。主要分为两个过程:
(1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中。
(2)收集,将放置在0~9号桶中的数据按顺序放到数组中。

实现:
最高位优先法(Most significant digit first)法,简称MSD法:先按K1排序,同一组中记录,关键码k1相等,再对各组按k2排序成分子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。

最低位优先(least significant digit)法:简称LSD法:先从kd开始排序,再对kd-1进行排序,一次重复,直到对k1排序后边得到一个有序序列。

算法分析

时间复杂性
设待排序列为N个记录,d个关键码,关键码的取值范围是radix,则进行链式基数排序的时间复杂度为:O(d(N + radix)),其中,一趟分配时间复杂度为O(N),一趟收集时间复杂度为O(radix),共进行d趟分配和收集。

空间复杂度
需要2*radix指向队列的辅助空间,已经用于静态链表的n个指针

稳定性
要看实现,如果是使用最低位优先,基数排序是一种稳定排序算法

实现

1、golang实现

package main

import (
    "fmt"
)

//求数据的最大位
func maxbit(values []int) (ret int) {
    ret = 1 //保存最大的位数
    var key int = 10
    iLen := len(values)
    for i := 0; i < iLen; i++ {
        for values[i] >= key {
            key = key * 10
            ret++
        }
    }
    return
}

func radixsort(values []int) {
    key := maxbit(values)
    iLen := len(values)
    tmp := make([]int, iLen, iLen)
    count := new([10]int)
    radix := 1
    var i, j, k int
    for i = 0; i < key; i++ { //进行key次排序
        for j = 0; j < 10; j++ {
            count[j] = 0
        }
        for j = 0; j < iLen; j++ {
            k = (values[j] / radix) % 10
            count[k]++
        }

        for j = 1; j < 10; j++ { //将tmp中的为准依次分配给每个桶
            count[j] = count[j-1] + count[j]
        }
        for j = iLen - 1; j >= 0; j-- {
            k = (values[j] / radix) % 10
            tmp[count[k]-1] = values[j]
            count[k]--
        }
        for j = 0; j < iLen; j++ {
            values[j] = tmp[j]
        }
        radix = radix * 10
    }
}

func main() {
    values := []int{2, 4, 7, 5, 8, 1, 3, 6, 6}
    fmt.Println(values)
    radixsort(values)
    fmt.Println(values)
    return
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值