桶排序
概念:
参考:桶排序
-
桶排序(Bucket Sort)的原理很简单,它是将数组分到有限数量的桶子里。
-
桶的结构:
List<LinkedList<Integer>>
,也就是Hash结构,是一种映射 -
Hashmap的储存也是用到了桶结构:
-
在将数据放到桶中之后,再通过一定的算法,将桶中的数据提出来,并转换成有序数组。就得到我们想要的结果了
-
实现:
-
规定桶的数量为100后,随机数字的范围也被限制在了100
public class BucketSort { public List<Integer> sort(List<Integer> A) { int k = 100; List<LinkedList<Integer>> buckets = new ArrayList<>(); List<Integer> list = new ArrayList<>(); for (int i = 0; i < k; i++) { buckets.add(new LinkedList<>()); } for (Integer item : A) { buckets.get(item % k).add(item); } for (LinkedList<Integer> bucket : buckets) { list.addAll(bucket); } return list; } } //测试类: @Test public void test_bucketSort() { BucketSort bucketSort = new BucketSort(); ArrayList<Integer> l = new ArrayList<>(); for (int i = 0; i < 1000000; i++) { //超过100则需要对桶内元素进行排序 l.add((int) (Math.random() * 100)); } long start = System.currentTimeMillis(); List<Integer> A = bucketSort.sort(l); System.out.println("time:" + (System.currentTimeMillis() - start)); assertSorted(A); }
此时能在桶内发现众多重复数据,但是因为是范围被限制住了;通过求模运算使得同一个桶内的数组都相同,因此不需要对桶进行排序:
假设没有限制范围:
-
推广至一般桶排序:
public class BucketSort { //A:集合。K:桶的数量 max:集合元素最大值 min:集合元素最小值 public List<Integer> sort(List<Integer> A, int k, int max, int min) { List<LinkedList<Integer>> buckets = new ArrayList<>(); List<Integer> list = new ArrayList<>(); int D = max - min + 1; QuickSort quickSort = new QuickSort(); for (int i = 0; i < k; i++) { buckets.add(new LinkedList<>()); } // 放入桶中 for (Integer item : A) { Integer key = (item - min) * k / D; buckets.get(key).add(item); } //从桶中取出值 for (int i = 0; i < k; i++) { //借助快排对桶内元素进行排序 list.addAll(quickSort.sort(buckets.get(i))); } return list; } } //测试类: @Test public void test_bucketSort1() { BucketSort1 bucketSort = new BucketSort1(); ArrayList<Integer> l = new ArrayList<>(); for (int i = 0; i < 1000000; i++) { l.add(100 + (int) (Math.random() * 1000)); } long start = System.currentTimeMillis(); List<Integer> A = bucketSort.sort(l, 10, 1100, 100); System.out.println("time:" + (System.currentTimeMillis() - start)); assertSorted(A); }
小结:
-
是稳定的排序算法:
-
稳定性是指,比如a在b前面,a=b,排序后,a仍然应该在b前面,这样就算稳定的。
-
桶排序中,假如升序排列,a已经在桶中,b插进来是永远都会a右边的(因为一般是从右到左,如果不小于当前元素,则插入改元素的右侧)
-
所以桶排序是稳定的
PS:当然了,如果采用元素插入后再分别进行桶内排序,并且桶内排序算法采用快速排序,那么就不是稳定的
-
更重要:桶排序的稳定性取决于桶内排序使用的算法。
-