计数排序

计数排序算法——时间复杂度O(n+k)

我与影子孤独终老i 提交于 2020-01-30 00:43:22
计数排序 计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。 算法思想 计数排序对输入的数据有附加的限制条件: 1、输入的线性表的元素属于有限偏序集S; 2、设输入的线性表的长度为n,|S|=k(表示集合S中元素的总数目为k),则k=O(n)。 在这两个条件下,计数排序的复杂性为O(n)。 计数排序的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。例如,如果输入序列中只有17个元素的值小于x的值,则x可以直接存放在输出序列的第18个位置上。当然,如果有多个元素具有相同的值时,我们不能将这些元素放在输出序列的同一个位置上,因此,上述方案还要作适当的修改。 假设输入的线性表L的长度为n,L=L1,L2,..,Ln;线性表的元素属于有限偏序集S,|S|=k且k=O(n),S={S1,S2,..Sk};则计数排序可以描述如下: 1、扫描整个集合S,对每一个Si∈S,找到在线性表L中小于等于Si的元素的个数T(Si); 2、扫描整个线性表L,对L中的每一个元素Li,将Li放在输出线性表的第T(Li)个位置上,并将T(Li)减1。

桶排序之计数排序与基数排序

大憨熊 提交于 2020-01-29 09:28:55
桶排序之计数排序和基数排序 桶排序 一种常见的排序算法,工作原理是将数组分到有限数量的桶子里,每个桶子再个别进行排序(会使用递归的方式继续使用桶排序进行排序或者使用其他的排序算法). 计数排序 计数排序是桶排序的一种特殊情况 从图中可以看出,待排序数字在[1,9]范围内; 创建9个空桶,将待排序数字分别放在对应的桶中; 再依次将桶中的元素按照桶的顺序拿出; 代码实现: public class CountSort { public static void main ( String [ ] args ) { int [ ] arr = { 2 , 4 , 2 , 3 , 7 , 1 , 1 , 1 , 0 , 5 , 6 , 9 , 8 , 7 , 4 , 0 , 9 } ; int [ ] result = sort ( arr ) ; System . out . println ( Arrays . toString ( result ) ) ; } static int [ ] sort ( int [ ] arr ) { //新建一个数组用来存放最终的结果 int [ ] result = new int [ arr . length ] ; //10个桶 int [ ] count = new int [ 10 ] ; //计数,计算每个桶中有多少个数字 for (

计数排序

核能气质少年 提交于 2020-01-23 08:29:51
/*其主要是将1同样大小的数据放在一起,然后在分开 */ #include <iostream> using namespace std; int SUM(int a[],int n) {//此函数为找到该数组最大值,作用为,开辟这么大的空间以防浪费 int max; max=a[0]; for(int i=1;i<n;i++) { if(a[i]>max) max=a[i]; } return max; } void paixu(int a[],int n) { int m=SUM(a,n); int i,j,b[10]={0}; for(i=0;i<n;i++) b[a[i]]++;//数组a对应的数组大小位置的b++,用b计量a[i]值的个数 for(i=0,j=0;i<=m && j<n;i++) { if(b[i]==1) a[j++]=i;//从新规划a[]因为b下标大小为a值大小 if(b[i]>1)//若b值大于1则代表有多个相同数(数大小为下标)将改变后的a中连续几位数设置相同 { int len=j; for(;j<=b[i]+len;j++) a[j]=i;//用len+b[i]来表示相同数结束位置 } //为0时不予处理 } } void main(){ int a[10]={1,1,5,7,1,1,4,0,0,0}; paixu(a,10); for

计数排序

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-19 17:44:03
计数排序有四个步骤: (1)首先会对每个输入进行频率统计,得到元素的频率表; (2)然后将频率表转换为该元素的 开始索引 ; (3)根据各个元素的开始索引,将相同元素分类到临时数组中。 (4)最后将临时数组中的元素写回到原数组中。 1 /*计数排序*/ 2 function countingSort(arr) { 3 //找到最大最小值,计算差值 4 var max_num = Math.max.apply(Math,arr); 5 console.log("max:"+max_num); 6 var min_num = Math.min.apply(Math,arr); 7 console.log("min:"+min_num); 8 var len = max_num-min_num+1; 9 //计算频率 10 var count = new Array(len + 1); 11 count.fill(0); //填充0 12 for (let i = 0; i < arr.length; i++) { 13 //使用加1的索引,有重复的地方自增 14 count[arr[i]-min_num+1]++; 15 } 16 console.log("count:"+count); 17 //计算开始索引 18 for (let i = 0; i < count.length-1

十大经典排序算法最强总结(含JAVA代码实现)(转载)

人走茶凉 提交于 2020-01-10 06:45:04
最近几天在研究排序算法,看了很多博客,发现网上有的文章中对排序算法解释的并不是很透彻,而且有很多代码都是错误的,例如有的文章中在“桶排序”算法中对每个桶进行排序直接使用了Collection.sort()函数,这样虽然能达到效果,但对于算法研究来讲是不可以的。所以我根据这几天看的文章,整理了一个较为完整的排序算法总结,本文中的所有算法均有JAVA实现,经本人调试无误后才发出,如有错误,请各位前辈指出。 0、排序算法说明 0.1 排序的定义 对一序列对象根据某个关键字进行排序。 0.2 术语说明 稳定 :如果a原本在b前面,而a=b,排序之后a仍然在b的前面; 不稳定 :如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面; 内排序 :所有排序操作都在内存中完成; 外排序 :由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行; 时间复杂度: 一个算法执行所耗费的时间。 空间复杂度 :运行完一个程序所需内存的大小。 0.3 算法总结 图片名词解释: n: 数据规模 k: “桶”的个数 In-place: 占用常数内存,不占用额外内存 Out-place: 占用额外内存 0.5 算法分类 0.6 比较和非比较的区别 常见的 快速排序、归并排序、堆排序、冒泡排序 等属于 比较排序 。 在排序的最终结果里,元素之间的次序依赖于它们之间的比较

算法系列-计数排序

邮差的信 提交于 2020-01-03 05:01:20
计数排序是一种算法复杂度 O(n) 的排序方法,适合于小范围集合的排序。比如100万学生参加高考,我们想对这100万学生的数学成绩(假设分数为0到100)做个排序。我们如何设计一个最高效的排序算法。本文不光给出计数排序算法的传统写法,还将一步步深入讨论算法的优化,直到时间复杂度和空间复杂度最优。 先看看计数排序的定义 Counting sort (sometimes referred to as ultra sort or math sort [1] ) is a sorting algorithm which (like bucket sort ) takes advantage of knowing the range of the numbers in the array to be sorted (array A ). It uses this range to create an array C of this length. Each index i in array C is then used to count how many elements in A have the value i ; then counts stored in C can then be used to put the elements in A into their right

计数排序

拈花ヽ惹草 提交于 2020-01-02 14:57:02
public static void main(String[] args) { int[] array={49,38,65,97,76,13,27,49,78,34,12,64,1}; int[] newArray = myCountSort(array); System.out.println("排序之后:"); for(int i=0;i<newArray.length;i++){ System.out.print(newArray[i]+" "); } System.out.println(); } public static int[] myCountSort(int[] arr){ int max=arr[0]; int min=arr[0]; for(int item:arr){ max=item>max?item:max; min=item<min?item:min; } //max-min+1为差值,这样的一个数组就可以存储min到max出现的次数了,min出现的次数存放在countArr[min-min] int[] countArr=new int[max-min+1]; for(int item:arr){ countArr[item-min]+=1; } // 计数累加,如果建立一个arr.length的新数组, // 那么min

十大经典排序算法

青春壹個敷衍的年華 提交于 2019-12-21 02:53:29
转自https://blog.csdn.net/hellozhxy/article/details/79911867 0、排序算法说明0.1 排序的定义 对一序列对象根据某个关键字进行排序。 0.2 术语说明 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面; 不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面; 内排序:所有排序操作都在内存中完成; 外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行; 时间复杂度: 一个算法执行所耗费的时间。 空间复杂度:运行完一个程序所需内存的大小。 例子 数据量低时,O(1) 和 O(n^2)的区别可以忽略不计。比如,你有个算法要处理2000条元素。 O(1) 算法会消耗 1 次运算 O(log(n)) 算法会消耗 7 次运算 O(n) 算法会消耗 2000 次运算 O(n*log(n)) 算法会消耗 14,000 次运算 O(n^2) 算法会消耗 4,000,000 次运算 O(1) 和 O(n^2) 的区别似乎很大(4百万),但你最多损失 2 毫秒,只是一眨眼的功夫。确实,当今处理器每秒可处理上亿次的运算。这就是为什么性能和优化在很多IT项目中不是问题。 我说过,面临海量数据的时候,了解这个概念依然很重要。如果这一次算法需要处理 1,000,000 条元素

计数排序 Rust实现

我的梦境 提交于 2019-12-20 00:29:57
计数排序 计数排序假设 n 个输入元素都是 0 到 k 区间的一个整数( k 为某整数) 当 k 为 O(n) 时,排序的时间为 O(n) 计数排序基本思想是:对于每个输入元素 x , 确定小于 x 的元素个数 先新建一个可变数组c, 初始化为0 let mut c: Vec<usize> = Vec::with_capacity(k); for i in 0..k+1 { c.push(0); } c记录a中每个元素出现的个数 for i in 0..a.len() { c[a[i]] = c[a[i]] + 1; } 然后计算对于 i 从 0..k , 有多少个元素是小于等于 i for i in 1..k+1 { c[i] = c[i] + c[i-1]; } 最后把元素a[i]放入数组b的正确位置上 for i in (0..a.len()).rev() { b[c[a[i]]-1] = a[i]; c[a[i]] = c[a[i]] - 1; } 计数排序的时间代价为 O(k+n) , 当 k=O(n) 时, 一般会采用计数排序 该排序不是比较排序, 而是根据元素的值来确定元素的位置 计数排序是稳定的 全部代码如下: fn count_sort(a: &mut [usize], b: &mut [usize], k: usize) { let mut c: Vec

排序算法:桶排序、计数排序、基数排序

Deadly 提交于 2019-12-06 22:29:39
相关博客: 排序算法:冒泡排序、插入排序、选择排序、希尔排序 排序算法:归并排序、快速排序 排序算法:桶排序、计数排序、基数排序 排序算法:堆排序 十大排序算法小结 这篇博客将主要介绍三种时间复杂度是O(n)的排序算法:桶排序、计数排序、计数排序。因为这些排序算法的时间复杂度都是线性的,所以也把这类排序算法称为 线性排序。 之所以能够做到线性的时间复杂度,主要原因是这几个算法是非基于比较的排序算法,不涉及元素之间的比较操作。 这几种排序算法的时间复杂度虽然低,但是对要排序的数据要求比较苛刻,所以我们关键是要知道这些排序算法的 适用场景 。 一、桶排序: 1、算法原理: 桶排序的核心思想就是将要排序的数据分到几个有序的桶里,每个桶里的数据再单独进行排序。桶排序完之后,再把每个桶里的数据按照顺序依次取出,组成的序列就是有序的了。 2、图片演示: 3、桶排序的时间复杂度为O(n): 如果要排序的数据有 n 个,我们把它们均匀地划分到 m 个桶内,每个桶里就有 k=n/m 个元素。每个桶内部使用归并排序,时间复杂度为 O(k * logk)。m 个桶排序的时间复杂度就是 O(m * k * logk),因为 k=n/m,所以整个桶排序的时间复杂度就是 O(n*log(n/m))。当桶的个数m 接近数据个数 n 时,log(n/m) 就是一个非常小的常量,这个时候桶排序的时间复杂度接近 O