From c4b579b463ba0b4b3fad263144179c139f1c1576 Mon Sep 17 00:00:00 2001 From: wgroeneveld Date: Sat, 24 Mar 2018 11:04:55 +0100 Subject: [PATCH] bucket sort --- .../be/brainbaking/sorting/BucketSort.java | 70 +++++++++++++++++++ .../be/brainbaking/sorting/InsertionSort.java | 2 + .../test/be/brainbaking/sorting/SortTest.java | 5 ++ 3 files changed, 77 insertions(+) create mode 100644 sorting/java/src/be/brainbaking/sorting/BucketSort.java diff --git a/sorting/java/src/be/brainbaking/sorting/BucketSort.java b/sorting/java/src/be/brainbaking/sorting/BucketSort.java new file mode 100644 index 0000000..06fa632 --- /dev/null +++ b/sorting/java/src/be/brainbaking/sorting/BucketSort.java @@ -0,0 +1,70 @@ +package be.brainbaking.sorting; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class BucketSort implements Sortable { + + private final InsertionSort insertionSorter; + + public BucketSort() { + this.insertionSorter = new InsertionSort(); + } + + /** + * n <- length[A] + * for i <- 1 to n + * do insert A[i] into list B[n*A[i]] rounded down + * for i <- 0 to n - 1 + * do sort list B[i] with insertion srot + * concatenate lists B[0], B[1], ..., B[n - 1] together + * @param list A + * @return sorted list + */ + @Override + public List sort(List list) { + int n = list.size(); + List> buckets = initializeBuckets(n); + + for(int i = 1; i <= n; i++) { + int x = list.get(i - 1); + int bucketIndex = calculateBucketIndex(n, x); + + if(buckets.size() <= bucketIndex) { + buckets.add(bucketIndex, Arrays.asList(x)); + } else { + buckets.get(bucketIndex).add(x); + } + } + + return mergeSortedBuckets(buckets); + } + + private List mergeSortedBuckets(List> buckets) { + List sorted = new ArrayList<>(); + for (List bucket : buckets) { + sorted.addAll(insertionSorter.sort(bucket)); + } + + return sorted; + } + + private List> initializeBuckets(int n) { + List> buckets = new ArrayList<>(); + + for(int i = 0; i < n; i++) { + buckets.add(new ArrayList<>()); + } + + return buckets; + } + + /** + * bucket sorting gaat uit van een uniforme distributie waarbij 0 <= A[i] <= 1 + * deel x door 10 in dit simpel voorbeeld. + */ + private int calculateBucketIndex(int n, int x) { + return (int)Math.floor(n * ((double) x / 10)); + } +} diff --git a/sorting/java/src/be/brainbaking/sorting/InsertionSort.java b/sorting/java/src/be/brainbaking/sorting/InsertionSort.java index 84927cb..a6b108e 100644 --- a/sorting/java/src/be/brainbaking/sorting/InsertionSort.java +++ b/sorting/java/src/be/brainbaking/sorting/InsertionSort.java @@ -6,6 +6,8 @@ import java.util.List; public class InsertionSort implements Sortable { public List sort(List list) { + if(list.size() == 0) return list; + // not the same thing, I don't want to mutate the incoming list. // start with nothing and insert it into the right position of result list. // ex. https://www.geeksforgeeks.org/insertion-sort/ diff --git a/sorting/java/test/be/brainbaking/sorting/SortTest.java b/sorting/java/test/be/brainbaking/sorting/SortTest.java index 3536544..b329a88 100644 --- a/sorting/java/test/be/brainbaking/sorting/SortTest.java +++ b/sorting/java/test/be/brainbaking/sorting/SortTest.java @@ -8,6 +8,11 @@ import java.util.List; public class SortTest { + @Test + public void bucketSort() { + simpleTestCaseFor(new BucketSort()); + } + @Test public void quickSort() { simpleTestCaseFor(new QuickSort());