桶排序、计数排序、基数排序

计数排序

核心思想:申请一个(max-min)+1 的桶, 将最小值作为基底。

代码:

func countingSort(a []int) {
    aLen := len(a)
    if aLen <= 1 {
        return
    }
    //1. 找出数组a中,元素最大的数,申请切片
    max := getMax(a)
    //2. 申请max+1 切片,这样数组中的每个数都能保证有一个桶
    //切片s,下标为a元素,值为元素个数,s为桶
    s := make([]int, max+1)
    //3. 遍历数组a,计算元素个数
    for i := 0; i < aLen; i++ {
        s[a[i]]++
    }
    //4. 顺序求数组和,目的是让统计数组存储的元素值,等于相应整数的最终排序位置。
    //比如下标是9的元素值为5,代表原始数列的整数9,最终的排序是在第5位。
    for i := 1; i <= max ; i++ {
        s[i] = s[i-1] + s[i]
    }
    //5. 输出数组r,用于排好序的数组,大小应和数组a相同
    r := make([]int, aLen)
    //6. 将数组a从后向前遍历(可以保证稳定性), 并查询数组c中的个数,将 个数-1 作为下标存储在r中,并将 个数-1
    for i := aLen-1; i >= 0; i-- {
        //s[i]为对应数组元素的个数
        index := s[a[i]] - 1
        r[index] = a[i]
        s[a[i]]--
    }
    //7. 将数组r 数据覆盖数组a数据
    copy(a, r)    
}
func getMax(a []int) int {
    max := a[0]
    for i := 1; i < len(a); i++ {
        if a[i] > max {
            max = a[i]
        }
    }
    return max 
}
复制代码

不足:如果一个要排序的数组数[90,92,93,90,91,97],则最大值为97,则申请的桶就为98,严重造成了资源的浪费,因为0-89下标没有任何用

优化:

func countingSort(a []int) {
    aLen := len(a)
    if aLen <= 1 {
        return
    }
    //1. 找出数组a中,元素最大的数,以及元素最小的数,申请切片
    max := getMax(a)
    min := getMin(a)
    //2. 申请max-min+1(不浪费内存) 切片,这样数组中的每个数都能保证有一个桶
    //切片s,下标为a元素,值为元素个数
    s := make([]int, max-min+1)
    //3. 遍历数组a,计算元素个数(使用最小值作为基底,存储元素个数)
    for i := 0; i < aLen; i++ {
        s[a[i]-min]++
    }
    //4. 顺序求数组和,目的是让统计数组存储的元素值,等于相应整数的最终排序位置。
    //比如下标是9的元素值为5,代表原始数列的整数9,最终的排序是在第5位。    
    for i := 1; i <= max-min; i++ {
        s[i] = s[i-1] + s[i]
    }
    //5. 输出数组r,用于排好序的数组,大小应和数组a相同
    r := make([]int, aLen)
    //6. 将数组a从后向前遍历(可以保证稳定性), 并查询数组c中的个数,将 个数-1 作为下标存储在r中,并将 个数-1
    for i := aLen-1; i >= 0; i-- {
        //s[i]为对应数组元素的个数
        index := s[a[i]-min] - 1
        r[index] = a[i]
        s[a[i]-min]--
    }
    //7. 将数组r 数据覆盖数组a数据
    copy(a, r)    
}
func getMax(a []int) int {
    max := a[0]
    for i := 1; i < len(a); i++ {
        if a[i] > max {
            max = a[i]
        }
    }
    return max 
}
func getMin(a []int) int {
    min := a[0]
    for i := 1; i < len(a); i++ {
        if a[i] < min {
            min = a[i]
        }
    }
    return min
}

复制代码
分类:
阅读
标签: