如果要对大量的一定范围内的数据进行排序,比如100000个0-99的数字进行排序,可以使用桶排序。
在设置了桶个数对应数字范围的情况下,时间复杂度O(N)
代码:
public List<Integer> sort(List<Integer> A) {int k = 100;ArrayList<LinkedList<Integer>> buckets = new ArrayList<>();ArrayList<Integer> list = new ArrayList<>();for (int i = 0; i < k; i++) {buckets.add(new LinkedList<>());}for (int item : A) {buckets.get(item % k).add(item);}for (LinkedList<Integer> bucket : buckets) {list.addAll(bucket);}return list;}
测试代码
@Testpublic void testBucketSort() {List<Integer> A = gen(100000);long startTime = System.currentTimeMillis();BucketSort bucketSort = new BucketSort();A = bucketSort.sort(A);assertSorted(A);System.out.println("Time: " + (System.currentTimeMillis() - startTime));}private List<Integer> gen(int n) {List<Integer> list = new ArrayList<>(n);for (int i = 0; i < n; i++) {list.add((int) (Math.random() * 100));}return list;}private void assertSorted(List<Integer> A) {Integer o = Integer.MIN_VALUE;for (int i : A) {if (o > i) {Assert.fail("Array not in sorted order");}o = i;}}
结果
Time: 27Process finished with exit code 0
使用归并排序时间=108
使用选择排序时间=1967
更通用的代码
多一个步骤:对桶内元素进行排序
public List<Integer> sort(List<Integer> A, int k, int max, int min) {ArrayList<LinkedList<Integer>> buckets = new ArrayList<>();ArrayList<Integer> ret = new ArrayList<>();// min 到 max 之间的长度int D = max - min + 1;QuickSort quicksort = new QuickSort();// 初始化所有的桶for (int i = 0; i < k; i++) {buckets.add(new LinkedList<>());}// 把元素放到桶里for (int item : A) {// 计算的是 item 对应的是哪个桶int key = (item - min) * k / D;buckets.get(key).add(item);}// 将桶里的值排序后放回到结果集中for (int i = 0; i < k; i++) {ret.addAll(quicksort.sortList(buckets.get(i)));}return ret;}
