swift算法之排序:(九)基数排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lin1109221208/article/details/90694120

1、概述

基数排序属于分配式排序,又称 桶子法,他是透过键值的部分咨询,将要排序的元素分配至某些桶中,借以达到排序的作用。

基数排序是属于稳定性的排序

2、算法原理

基本原理:利用桶来实现,然后按照基数入桶,基数的取值是从数字的低位到高位以此取值

步骤:

1)以无序序列数值的个数为基数,将无序序列的值进入到基数对应的桶中

2)个位数为基数入桶完毕后,在安装编号从小到大将桶中的数据以此取出,再存入之前的数组中

3)在2中生成的数组的基础上再以式位数为基准入桶,入桶完毕后,再次按照桶的编号顺序将数值取出

注:排序的数值越大,入桶出桶的次数就越多,所以随着位数的增大,效率会降低

3、举例

以[62, 88, 58, 47, 62, 35, 73, 51, 99, 37, 93]排序为例

1)取个数为基数,以62为例,取个数为基数,62在本轮进入编号为2的桶中

2)1)排序完,在安装编号从大到小将桶中的数据取出,存入之前的数组

3)取十位数为基数入桶,排序完按顺序取出,数组中最高位是十位数,即十位数出桶入桶后,数组已经排序完成,如果还有高位,需要继续取基数排序,直到最高位排序完成

4、算法实现

//1、创建n个空桶
    /*
     返回结果的类型是Array<Array<Int>>,是一个二维数组。
     内层数组就是一个桶,负责存放与该桶编号相等的基数对应的数值
     */
    private func createBucket(_ n : Int)->Array<Array<Int>>{
        var bucket : Array<Array<Int>> = []
        for _ in 0..<n {
            bucket.append([])
        }
        return bucket
    }
    //2、计算无序序列中最大的那个数
    /*
     取基数入桶出桶的次数以此最大数值的位数为准
     */
    private func listMaxItem(_ list : Array<Int>)->Int{
        var maxNumber = list[0]
        for item in list {
            if maxNumber < item {
                maxNumber = item
            }
        }
        return maxNumber
    }
    //3、获取数字的长度----即取基数的次数
    private func numberLength(_ num : Int)->Int{
        return "\(num)".count
    }
    //4、获取数值中特定位数的值
    /*
     通过取余以及求模的方式获取 / 采用将数字转换成字符串,然后将字符串转换成字符串数组
     */
    private class func fetchBaseNumber(_ num : Int, _ digit : Int)->Int{
        if digit > 0 && digit<=SortSummary.numberLength(num) {
            var numArr : Array<Int> = []
            for char in "\(num)" {
                numArr.append(Int("\(char)")!)
            }
            return numArr[numArr.count-digit]
        }
        return 0
    }
    //5、排序
    func radixSort(_ list : inout Array<Int>){
        var bucket = createBucket(list.count)
        var maxNum = listMaxItem(list)
        let maxLength = numberLength(maxNum)
        
        for digit in 1...maxLength {
            //入桶
            for item in list {
                let baseNum = fetchBaseNumber(item, digit)
                //根据基数进入相应的桶中
                bucket[baseNum].append(item)
            }
            //出桶
            var index = 0
            for i in 0..<bucket.count{
                while !bucket[i].isEmpty {
                    list[index] = bucket[i].remove(at: 0)
                    index += 1
                }
            }
        }
    }



调用:
        var array9 = [62, 88, 58, 47, 62, 35, 73, 51, 99, 37, 93]
        radixSort(&array9)


运行结果:
[35, 37, 47, 51, 58, 62, 62, 73, 88, 93, 99] 

5、时间复杂度

基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集

github代码

注:排序的具体实现代码在 SortSummary.swift 文件里 调用是在 ViewController.swift

猜你喜欢

转载自blog.csdn.net/lin1109221208/article/details/90694120