Skip to content

Commit 0cd0ef2

Browse files
author
Alex Klymenko
committed
refactor: refactoring BucketSort implementation, adding more tests
1 parent 5113101 commit 0cd0ef2

File tree

2 files changed

+114
-92
lines changed

2 files changed

+114
-92
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,101 @@
11
package com.thealgorithms.sorts;
22

33
import java.util.ArrayList;
4+
import java.util.Arrays;
45
import java.util.Collections;
56
import java.util.List;
6-
import java.util.Random;
7+
import java.util.stream.Collectors;
8+
import java.util.stream.IntStream;
79

810
/**
9-
* Wikipedia: https://en.wikipedia.org/wiki/Bucket_sort
11+
* BucketSort class provides a static method to sort an array of integers using the Bucket Sort algorithm.
1012
*/
1113
public final class BucketSort {
1214
private BucketSort() {
1315
}
1416

15-
public static void main(String[] args) {
16-
int[] arr = new int[10];
17-
18-
/* generate 10 random numbers from -50 to 49 */
19-
Random random = new Random();
20-
for (int i = 0; i < arr.length; ++i) {
21-
arr[i] = random.nextInt(100) - 50;
22-
}
23-
24-
bucketSort(arr);
25-
26-
/* check array is sorted or not */
27-
for (int i = 0, limit = arr.length - 1; i < limit; ++i) {
28-
assert arr[i] <= arr[i + 1];
29-
}
30-
}
31-
3217
/**
33-
* BucketSort algorithms implements
18+
* Sorts the given array using the Bucket Sort algorithm.
3419
*
35-
* @param arr the array contains elements
20+
* @param arr the array to be sorted
21+
* @return the sorted array
3622
*/
3723
public static int[] bucketSort(int[] arr) {
38-
/* get max value of arr */
39-
int max = max(arr);
40-
41-
/* get min value of arr */
42-
int min = min(arr);
24+
if (arr.length == 0) {
25+
return arr;
26+
}
4327

44-
/* number of buckets */
28+
int min = Arrays.stream(arr).min().getAsInt();
29+
int max = Arrays.stream(arr).max().getAsInt();
4530
int numberOfBuckets = max - min + 1;
4631

47-
List<List<Integer>> buckets = new ArrayList<>(numberOfBuckets);
32+
List<List<Integer>> buckets = initializeBuckets(numberOfBuckets);
4833

49-
/* init buckets */
50-
for (int i = 0; i < numberOfBuckets; ++i) {
51-
buckets.add(new ArrayList<>());
52-
}
53-
54-
/* store elements to buckets */
55-
for (int value : arr) {
56-
int hash = hash(value, min, numberOfBuckets);
57-
buckets.get(hash).add(value);
58-
}
34+
distributeElementsToBuckets(arr, buckets, min, numberOfBuckets);
35+
sortBuckets(buckets);
5936

60-
/* sort individual bucket */
61-
for (List<Integer> bucket : buckets) {
62-
Collections.sort(bucket);
63-
}
37+
return concatenateBuckets(buckets, arr);
38+
}
6439

65-
/* concatenate buckets to origin array */
66-
int index = 0;
67-
for (List<Integer> bucket : buckets) {
68-
for (int value : bucket) {
69-
arr[index++] = value;
70-
}
71-
}
40+
/**
41+
* Initializes the buckets for sorting.
42+
*
43+
* @param numberOfBuckets the number of buckets to initialize
44+
* @return a list of empty buckets
45+
*/
46+
private static List<List<Integer>> initializeBuckets(final int numberOfBuckets) {
47+
return IntStream.range(0, numberOfBuckets)
48+
.mapToObj(i -> new ArrayList<Integer>())
49+
.collect(Collectors.toList());
50+
}
7251

73-
return arr;
52+
/**
53+
* Distributes the elements of the array into the appropriate buckets.
54+
*
55+
* @param arr the array to distribute
56+
* @param buckets the list of buckets
57+
* @param min the minimum value in the array
58+
* @param numberOfBuckets the total number of buckets
59+
*/
60+
private static void distributeElementsToBuckets(int[] arr, List<List<Integer>> buckets, final int min, final int numberOfBuckets) {
61+
Arrays.stream(arr).forEach(value -> buckets.get(hash(value, min, numberOfBuckets)).add(value));
7462
}
7563

7664
/**
77-
* Get index of bucket which of our elements gets placed into it.
65+
* Sorts each bucket individually.
7866
*
79-
* @param elem the element of array to be sorted
80-
* @param min min value of array
81-
* @param numberOfBucket the number of bucket
82-
* @return index of bucket
67+
* @param buckets the list of buckets to sort
8368
*/
84-
private static int hash(int elem, int min, int numberOfBucket) {
85-
return (elem - min) / numberOfBucket;
69+
private static void sortBuckets(List<List<Integer>> buckets) {
70+
buckets.forEach(Collections::sort);
8671
}
8772

8873
/**
89-
* Calculate max value of array
74+
* Concatenates the sorted buckets into the original array.
9075
*
91-
* @param arr the array contains elements
92-
* @return max value of given array
76+
* @param buckets the list of sorted buckets
77+
* @param arr the original array
78+
* @return the sorted array
9379
*/
94-
public static int max(int[] arr) {
95-
int max = arr[0];
96-
for (int value : arr) {
97-
if (value > max) {
98-
max = value;
80+
private static int[] concatenateBuckets(List<List<Integer>> buckets, int[] arr) {
81+
int index = 0;
82+
for (List<Integer> bucket : buckets) {
83+
for (int value : bucket) {
84+
arr[index++] = value;
9985
}
10086
}
101-
return max;
87+
return arr;
10288
}
10389

10490
/**
105-
* Calculate min value of array
91+
* Computes the hash value to determine which bucket an element should be placed in.
10692
*
107-
* @param arr the array contains elements
108-
* @return min value of given array
93+
* @param element the element of the array
94+
* @param min the minimum value in the array
95+
* @param numberOfBuckets the total number of buckets
96+
* @return the index of the bucket
10997
*/
110-
public static int min(int[] arr) {
111-
int min = arr[0];
112-
for (int value : arr) {
113-
if (value < min) {
114-
min = value;
115-
}
116-
}
117-
return min;
98+
private static int hash(final int element, final int min, final int numberOfBuckets) {
99+
return (element - min) / numberOfBuckets;
118100
}
119101
}

src/test/java/com/thealgorithms/sorts/BucketSortTest.java

+55-15
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,82 @@
77
public class BucketSortTest {
88

99
@Test
10-
public void bucketSortSingleIntegerArray() {
10+
public void sortSingleIntegerArray() {
1111
int[] inputArray = {4};
12-
int[] outputArray = BucketSort.bucketSort(inputArray);
1312
int[] expectedOutput = {4};
14-
assertArrayEquals(outputArray, expectedOutput);
13+
int[] outputArray = BucketSort.bucketSort(inputArray);
14+
assertArrayEquals(expectedOutput, outputArray);
1515
}
1616

1717
@Test
18-
public void bucketSortNonDuplicateIntegerArray() {
19-
int[] inputArray = {6, 1, 99, 27, 15, 23, 36};
18+
public void sortEmptyArray() {
19+
int[] inputArray = {};
20+
int[] expectedOutput = {};
21+
int[] outputArray = BucketSort.bucketSort(inputArray);
22+
assertArrayEquals(expectedOutput, outputArray);
23+
}
24+
25+
@Test
26+
public void sortAlreadySortedArray() {
27+
int[] inputArray = {1, 2, 3, 4, 5, 6, 7};
28+
int[] expectedOutput = {1, 2, 3, 4, 5, 6, 7};
2029
int[] outputArray = BucketSort.bucketSort(inputArray);
30+
assertArrayEquals(expectedOutput, outputArray);
31+
}
32+
33+
@Test
34+
public void sortNonDuplicateIntegerArray() {
35+
int[] inputArray = {6, 1, 99, 27, 15, 23, 36};
2136
int[] expectedOutput = {1, 6, 15, 23, 27, 36, 99};
22-
assertArrayEquals(outputArray, expectedOutput);
37+
int[] outputArray = BucketSort.bucketSort(inputArray);
38+
assertArrayEquals(expectedOutput, outputArray);
2339
}
2440

2541
@Test
26-
public void bucketSortDuplicateIntegerArray() {
42+
public void sortDuplicateIntegerArray() {
2743
int[] inputArray = {6, 1, 27, 15, 23, 27, 36, 23};
28-
int[] outputArray = BucketSort.bucketSort(inputArray);
2944
int[] expectedOutput = {1, 6, 15, 23, 23, 27, 27, 36};
30-
assertArrayEquals(outputArray, expectedOutput);
45+
int[] outputArray = BucketSort.bucketSort(inputArray);
46+
assertArrayEquals(expectedOutput, outputArray);
3147
}
3248

3349
@Test
34-
public void bucketSortNonDuplicateIntegerArrayWithNegativeNum() {
50+
public void sortNonDuplicateIntegerArrayWithNegativeNum() {
3551
int[] inputArray = {6, -1, 99, 27, -15, 23, -36};
36-
int[] outputArray = BucketSort.bucketSort(inputArray);
3752
int[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99};
38-
assertArrayEquals(outputArray, expectedOutput);
53+
int[] outputArray = BucketSort.bucketSort(inputArray);
54+
assertArrayEquals(expectedOutput, outputArray);
3955
}
4056

4157
@Test
42-
public void bucketSortDuplicateIntegerArrayWithNegativeNum() {
58+
public void sortDuplicateIntegerArrayWithNegativeNum() {
4359
int[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23};
44-
int[] outputArray = BucketSort.bucketSort(inputArray);
4560
int[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27};
46-
assertArrayEquals(outputArray, expectedOutput);
61+
int[] outputArray = BucketSort.bucketSort(inputArray);
62+
assertArrayEquals(expectedOutput, outputArray);
63+
}
64+
65+
@Test
66+
public void sortLargeArray() {
67+
int[] inputArray = {100, 50, -100, 200, 0, 150, -50};
68+
int[] expectedOutput = {-100, -50, 0, 50, 100, 150, 200};
69+
int[] outputArray = BucketSort.bucketSort(inputArray);
70+
assertArrayEquals(expectedOutput, outputArray);
71+
}
72+
73+
@Test
74+
public void sortArrayWithAllIdenticalElements() {
75+
int[] inputArray = {5, 5, 5, 5, 5};
76+
int[] expectedOutput = {5, 5, 5, 5, 5};
77+
int[] outputArray = BucketSort.bucketSort(inputArray);
78+
assertArrayEquals(expectedOutput, outputArray);
79+
}
80+
81+
@Test
82+
public void sortArrayWithMixedPositiveAndNegativeNumbers() {
83+
int[] inputArray = {-3, 0, 2, -2, 3, 1, -1};
84+
int[] expectedOutput = {-3, -2, -1, 0, 1, 2, 3};
85+
int[] outputArray = BucketSort.bucketSort(inputArray);
86+
assertArrayEquals(expectedOutput, outputArray);
4787
}
4888
}

0 commit comments

Comments
 (0)