桶排序

  • 计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。计数排序不是比较排序,所以他优于任何比较排序。

  • 我们将一个数组所有数字出现的次数,统计出来,放入一个辅助数组中,然后把辅助数组中统计的数组从小到大,按每个数出现的次数,有几次输出几次就可以得到一个有序的序列。

    图源:https://www.runoob.com/w3cnote/counting-sort.html

例如: 给定一组学生年龄数组,要求给该数组进行计数排序,我们知道年龄的范围是0~200之间,

以下给出python语言的排序代码:

def countingSort(arr,maxValue):
{#桶的长度是数组中数字最大的数的数值bucketlen=maxValue+1#将桶内数组全部置零 用于统计出现次数bucket = [0]*bucketlensorttedIndex=0arrLen=len(arr)for i in range(arrlen):if not bucket[arr[i]]:bucket[arr[i]]=0bucket[arr[i]]+=1for j in range(bucketlen):while bucket[j]>0:arr[sorttedIndex]=jsorttedIndex+=1bucket[j]-=1return arr
}

基数排序

  • 基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

    图源:https://www.runoob.com/w3cnote/radix-sort.html

思考: 准备10个队列(0~9),将每个数字从个位开始,依次放在相应位置上,并且一个“桶中”如果有多个数字,就按先入先出的原则将每个数输出,这样就保证的这一位上的数字依然是从小到大有序的,进而将这种有序性一直传递了下去。

代码算法

利用了一个极其精巧的方式,可以不需要队列完成先入先出的操作。理解起来还是有一点难度的,如下图解释:

以下是以个位数为基准的一次排序过程,完整的过程是分别对个位、十位、百位进行如下的操作:


Java语言描述的代码如下:

//arr[L...R]排序 digit是最大的数字有多少个十进制位,
//也就是最大值的数 位数
public static radixSort(int[] arr,int L,int R,int digit)
{final int radix=10;int i=0,j=0;//有多少个数准备多少个辅助空间int[] bucket=new int[R-L+1];//有多少位就操作几次for(int d=1;d<=digit;d++){int[] count=new int[radix];for(i=L;i<=R;i++){//得到倒数第d位上的数字是几j=getDigit(arr[i],d);count[j]++;}//创建count‘数组,count[0]上的数字不变for(i=1;i<radix;i++)count[i]=count[i]+count[i-1];//从右向左遍历arr数组for(i=R;i>=L;i--){j=getDigit(arr[i],d);bucket[arr[j]-1]=arr[i];count[j]--;}//把某一位有序的数组copy回原数组for(i=L,j=0;i<=R;i++,j++){arr[i]=bucket[j];}}
}//返回x这个数在倒数第d位上的数是几
public static int getDigit(int x,int d)
{return ( ( x/ ( (int)Math.pow(10,d-1) ) ) %10 );
}//返回最大值的位数
public static int maxbits(int[] arr){int max=Integer.MIN_VALUE;for(int i=0;i<arr.length;i++){max=Math.max(max,arr[i]);}int res=0;while(max!=0){res++;max/=10;}return res;
}public static void main()
{int[] arr={022,021,032,001,100}if(arr==null||arr.length<2){return;}radixSort(arr,0,arr.length-1,maxbits(arr));
}

时间复杂度

O( log(10,max)*N )
max有log(10,max)个十进制位,所以遍历了log(10,max)次数组,数组中共有N个数字。
在计算机中,十进制位有限,所以时间复杂度为O(N)。

不基于比较的排序时间复杂度很小,但是应用的范围很有限。基于排序的比较是比较实用的,应用范围较广。

左神桶排序和基数排序相关推荐

  1. 十大排序算法:冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序

    冒泡排序.选择排序.插入排序.希尔排序.归并排序.快速排序.堆排序.计数排序.桶排序.基数排序的动图与源代码. 目录 关于时间复杂度 冒泡排序 选择排序 插入排序 希尔排序 归并排序 快速排序 堆排序 ...

  2. 计数排序、桶排序和基数排序

    计数排序 当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k).计数排序不是比较排序,排序的速度快于任何比较排序算法. 由于用来计数的数组C的长度取决于待排序数组中数据的 ...

  3. 三种线性排序算法 计数排序、桶排序与基数排序-BYVoid

    转自:BYVoid [非基于比较的排序] 在计算机科学中,排序是一门基础的算法技术,许多算法都要以此作为基础,不同的排序算法有着不同的时间开销和空间开销.排序算法有非常多种,如我们最常用的快速排序和堆 ...

  4. 三种线性排序算法 计数排序、桶排序与基数排序—— 转自:BYVoid

    三种线性排序算法 计数排序.桶排序与基数排序 [非基于比较的排序] 在计算机科学中,排序是一门基础的算法技术,许多算法都要以此作为基础,不同的排序算法有着不同的时间开销和空间开销.排序算法有非常多种, ...

  5. 十大经典排序算法(图解与代码)——冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序(Python and Java)

    排序 重新排列表中的元素,使表中的元素按照关键字递增或者递减 内部排序: 指在排序期间,元素全部存放在内存中的排序 外部排序: 指在排序期间元素无法全部同时存放在内存中,必须在排序的过程中根据要求不断 ...

  6. 十大排序算法详解(二)归并排序、堆排序、计数排序、桶排序、基数排序

    文章目录 一.归并排序 1.1 归并排序基础[必会知识] 1.1.1 递归实现 1.1.2 非递归实现 1.2 归并排序优化 1.2.1 小数组使用插入排序 1.2.2 避免多余比较 1.2.3 节省 ...

  7. 计数排序、桶排序和基数排序的运算性能对比及总结区别(附python代码)

    首先证明一波排序算法的运算性能,如下图.对于50万个数据的无序列表,时间复杂度为的桶排序和计数排序明显比复杂度为的归并排序和快速排序性能好至少一个数量级. 1. 计数排序  1.1 基本原理:首先确定 ...

  8. 【完整可运行源码+GIF动画演示】十大经典排序算法系列——冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序

    以前也零零碎碎发过一些排序算法,但总是不系统, 这次彻底的对排序系列做了一个整体的规划, 小伙伴们快快mark哦~ [GIF动画+完整可运行源代码]C++实现 冒泡排序--十大经典排序算法之一 [GI ...

  9. 【数据结构笔记38】桶排序、基数排序、多关键字排序、排序算法汇总比较

    本次笔记内容: 10.3.1 桶排序 10.3.2 基数排序 10.3.3 多关键字排序 10.4 排序算法比较 文章目录 排序算法背景 桶排序 基数排序 多关键字排序(基数排序) 排序算法的比较 排 ...

最新文章

  1. 【细品架构8/100】好代码是架构的根基
  2. 农牧行业销售经理生存手册(二)
  3. .NET Core 中的并发编程
  4. 蚂蚁财富联手百会CRM全面升级金融服务
  5. 从0开始学习GitHub系列之「认识并加入GitHub」
  6. intellij2019.1 破jie不了的解决办法
  7. java 中映射关系_java – 在Hibernate中映射一对多的关系?
  8. IOS中的swift和oc关于对象模型的description方法重写
  9. ADPC2-G 希望
  10. php字符集转换,php字符集转换
  11. springboot实体映射到数据库_SpringBoot 操作 ElasticSearch 详解
  12. 安装Visual Studio 2008系统要求
  13. python 进化树_7款物种分类(进化树地位)信息检索工具使用方法
  14. 毕业设计-电子商务网站(二)
  15. 中山技术学院计算机学院,计算机科学与技术学院
  16. linux 读取内存颗粒,Linux中的内存管理模型浅析
  17. 模仿探探(百合网,珍爱网)卡片左右滑动效果,滑动流畅,卡片view无限重生
  18. 程序猿和测试媛——组合在一起的原因
  19. kartoSLAM报错 transform_tolerance修改解决
  20. FPAG—计数器—BCD译码器—Verilog

热门文章

  1. 使用CrashHandler来获取应用的crash信息
  2. 《Spring实战》系列之Bean的装配-Days01
  3. 【教程】条形码组件Spire.Barcode 教程:如何在C#中创建DataMatrix条码
  4. 利用sql_trace跟踪一个指定会话的操作
  5. Android Calender
  6. 类文件Spring中空值的写法-java教程
  7. 面试官系统精讲Java源码及大厂真题 - 16 ConcurrentHashMap 源码解析和设计思路
  8. Docker的今生前世,关于Docker的一些见解
  9. 分布式面试 - dubbo 的 spi 思想是什么?
  10. 如何在CentOS 7上使用HAproxy Loadbalancer设置Percona XtraDB集群(负载均衡)