计数排序
来源:互联网 发布:淘宝保证金别骗怎么办 编辑:程序博客网 时间:2024/04/27 22:42
基本思想: 对每一个输入元素x,确定出小于x的元素个数。有了这一信息,就可以把x直接放到它在最终输出数组中的位置上。例如,如果有17个元素小于x,则x就属于第18个输出位置。
计数排序是一个非基于比较的排序算法。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。当然这是一种牺牲空间换取时间的做法,而且当O(k)>O*(n*log(n))的时候其效率反而不如基于比较的排序(基于比较的排序的时间复杂度在理论上的下限是*O(n*log(n)), 如归并排序,堆排序),计数排序是稳定的。
算法过程: 假设输入的线性表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。
给定数组a[8]={2,5,3,0,2,3,0,3};
Java代码:
public class LinearTimeSorter { /** * 计数排序,所有的元素都在0和max之间。 */ public static void countingSort(int[] array, int fromIndex, int toIndex, int max) { int[] counting = new int[max + 1]; for (int i = fromIndex; i < toIndex; i++) { counting[array[i]]++; } // counting[i]现在包含值为i的个数 for (int i = 1; i < counting.length; i++) { counting[i] += counting[i-1]; } // counting[i]现在包含值小于等于i的个数 int[] tempArray = new int[toIndex - fromIndex]; for (int i = toIndex - 1; i >= 0; i--) { // 注意:这里是反向遍历,只有这样才是稳定的 tempArray[--counting[array[i]]] = array[i]; } // copy back System.arraycopy(tempArray, 0, array, fromIndex, tempArray.length); } public static void countingSort(int[] array, int max) { countingSort(array, 0, array.length, max); } /** * 计数排序,所有的元素都在min和max之间。 */ public static void countingSortMinMax(int[] array, int fromIndex, int toIndex, int min, int max) { int[] counting = new int[max - min + 1]; for (int i = fromIndex; i < toIndex; i++) { counting[array[i]-min]++; } // counting[i]现在包含值为(i+min)的个数 for (int i = 1; i < counting.length; i++) { counting[i] += counting[i-1]; } // counting[i]现在包含值小于等于(i+min)的个数 int[] tempArray = new int[toIndex - fromIndex]; for (int i = toIndex - 1; i >= 0; i--) { tempArray[--counting[array[i] - min]] = array[i]; } // copy back System.arraycopy(tempArray, 0, array, fromIndex, tempArray.length); } public static void countingSortMinMax(int[] array, int min, int max) { countingSortMinMax(array, 0, array.length, min, max); } /** * 计数排序,自动决定min和max。 */ public static void countingSort(int[] array) { if (array.length <= 1) return; int min = array[0]; int max = array[0]; for (int i = 1; i < array.length; i++) { if (min > array[i]) min = array[i]; if (max < array[i]) max = array[i]; } countingSortMinMax(array, min, max); } public static void main(String[] args) { int[] a = new int[] {2, 5, 3, 0, 2, 3, 0, 3}; countingSort(a, 5); System.out.println(Arrays.toString(a)); a = new int[] {0, 3, 1, -2, 0, 1, -2, 1}; countingSortMinMax(a, -2, 3); System.out.println(Arrays.toString(a)); }}
0 0
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 计数排序
- 淘宝分布式调度框架TBSchedule
- 微服务(Microservice)那点事
- 中断调试小结
- 字符串求最长公共子序列(相似度计算)
- 悬链线
- 计数排序
- javaweb第一课,Tomcat的安装和配置
- 【寒假任务】洛谷1067 多项式输出
- leetcode141&234
- 如何对n个大小都小于100的整数进行排序,要求时间复杂度O(n),空间复杂度O(1)。
- GLSL语言基础
- 流式布局(一)
- 输入一个正数n,输出所有和为n连续正数序列。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3个连续序列1-5、4-6和7-8。
- 两台Linux之间传输文件