计数排序介绍、详解、案例

9 篇文章 0 订阅

排序

序言

排序是非常基础并且重要的算法,目前常见的排序算法有插入排序冒泡排序堆排序计数排序归并排序快速排序等。

计数排序

计数排序是一种线性时间的整数排序算法。如果数组的长度为n,整数范围(数组中最大值和最小值的差值)为K,若k远小于n,则计数排序的时间效率会远小于插入、归并排序等。如对公司员工的年龄进行排序,就可以考虑计数排序。

排序思想

统计数组中每个数字出现的次数,然后按照数字从小到大的顺序依次填充到数组中去。

  1. 比如数组[2 , 3 , 4 , 2 , 3 , 2 , 1 ],可以计算出差值k为3;
  2. 此时我们准备一个容量为4(k+1)的数组Array,在对应数组的位置存放每个值出现的次数。比如值2则存放到位置1,值3则存放到位置2,值4则存放到位置3,值1则是位置0;
  3. 最终Array会变成这个样子[1 , 3 , 2 , 1],代表1出现了1次,2出现了3次,3出现了2两次,4出现了1次。
  4. 依次读取Array数组,即可知道排序结果[1 , 2 , 2 , 2 , 3 , 3 , 4]。

代码实现

fun countSortArray(array: IntArray) {
    //获取最大值和最小值
    var maxValue = Int.MIN_VALUE
    var minValue = Int.MAX_VALUE
    array.forEach {
        maxValue = Math.max(maxValue, it)
        minValue = Math.min(minValue, it)
    }
	//利用最大值和最小值准备空数组 , 并且存放对应值的出现的次数
    val snapArray = IntArray(maxValue - minValue + 1)
    array.forEach {
        val index = it - minValue
        val snapCount = snapArray[index]
        snapArray[index] = snapCount + 1
    }
	//依次读取数组,进行值排序
    var index = 0
    for (i in snapArray.indices) {
        val value = snapArray[i]
        var count = value
        while (count > 0) {
            array[index++] = i + minValue
            count--
        }
    }
}

时间复杂度:数组的长度为n,整数范围为k,所以时间复杂度为O(n+k)。

空间复杂度:需要创建一个长度为(k+1)的数组进行辅助,所以控件复杂度为O(K)。

示例

存在两个数组arr1arr2arr2中的每一个数组都唯一且是arr1中的数字。要求arr1中的数字要按照arr2进行相对排序。如果数组arr1中存在arr2中没有的数字,则按照递增的顺序排在后面。设定数组中的数字均在1000范围内。

列如:arr1是[2 , 3 , 3 , 7 , 3 , 9 , 2 , 1 , 7 , 2],arr2是[3 , 2 , 1]。则排序的结果为[3 , 3 , 3 , 2 , 2 , 2 , 1 , 7 , 9]。

分析:1000范围内,所以k即为1000,考虑计数排序。之后现根据数组arr2输出,然后按照大小输出。

fun countSortArrayQuestion(array1: IntArray, array2: IntArray) {
    //根据差值 计算每个数字出现的频率
    val diffValue = 1000
    val snapArray = IntArray(diffValue + 1)
    array1.forEach {
        val index = it
        val snapCount = snapArray[index]
        snapArray[index] = snapCount + 1
    }

    var index = 0
    //首先排序arr2中存在的
    array2.forEach {
        val value = snapArray[it]
        var count = value
        while (count > 0) {
            array1[index++] = it
            count--
        }
        //清空
        snapArray[it] = 0
    }
	//剩余排序
    for (i in snapArray.indices) {
        val value = snapArray[i]
        var count = value
        while (count > 0) {
            array1[index++] = i
            count--
        }
    }
}

🙆‍♀️。欢迎技术探讨噢!

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pumpkin的玄学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值