mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-12 22:56:11 +08:00
refactor: cleanup BucketSort
(#5314)
This commit is contained in:
@ -3,117 +3,128 @@ package com.thealgorithms.sorts;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wikipedia: https://en.wikipedia.org/wiki/Bucket_sort
|
* BucketSort class provides a method to sort an array of elements using the Bucket Sort algorithm
|
||||||
|
* and implements the SortAlgorithm interface.
|
||||||
*/
|
*/
|
||||||
public final class BucketSort {
|
public class BucketSort implements SortAlgorithm {
|
||||||
private BucketSort() {
|
|
||||||
|
// Constant that defines the divisor for determining the number of buckets
|
||||||
|
private static final int BUCKET_DIVISOR = 10;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Comparable<T>> T[] sort(T[] array) {
|
||||||
|
if (array.length == 0) {
|
||||||
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
T min = findMin(array);
|
||||||
int[] arr = new int[10];
|
T max = findMax(array);
|
||||||
|
int numberOfBuckets = calculateNumberOfBuckets(array.length);
|
||||||
|
|
||||||
/* generate 10 random numbers from -50 to 49 */
|
List<List<T>> buckets = initializeBuckets(numberOfBuckets);
|
||||||
Random random = new Random();
|
distributeElementsIntoBuckets(array, buckets, min, max, numberOfBuckets);
|
||||||
for (int i = 0; i < arr.length; ++i) {
|
|
||||||
arr[i] = random.nextInt(100) - 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
bucketSort(arr);
|
return concatenateBuckets(buckets, array);
|
||||||
|
|
||||||
/* check array is sorted or not */
|
|
||||||
for (int i = 0, limit = arr.length - 1; i < limit; ++i) {
|
|
||||||
assert arr[i] <= arr[i + 1];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BucketSort algorithms implements
|
* Calculates the number of buckets to use based on the size of the array.
|
||||||
*
|
*
|
||||||
* @param arr the array contains elements
|
* @param arrayLength the length of the array
|
||||||
|
* @return the number of buckets
|
||||||
*/
|
*/
|
||||||
public static int[] bucketSort(int[] arr) {
|
private int calculateNumberOfBuckets(final int arrayLength) {
|
||||||
/* get max value of arr */
|
return Math.max(arrayLength / BUCKET_DIVISOR, 1);
|
||||||
int max = max(arr);
|
}
|
||||||
|
|
||||||
/* get min value of arr */
|
/**
|
||||||
int min = min(arr);
|
* Initializes a list of empty buckets.
|
||||||
|
*
|
||||||
/* number of buckets */
|
* @param numberOfBuckets the number of buckets to initialize
|
||||||
int numberOfBuckets = max - min + 1;
|
* @param <T> the type of elements to be sorted
|
||||||
|
* @return a list of empty buckets
|
||||||
List<List<Integer>> buckets = new ArrayList<>(numberOfBuckets);
|
*/
|
||||||
|
private <T extends Comparable<T>> List<List<T>> initializeBuckets(int numberOfBuckets) {
|
||||||
/* init buckets */
|
List<List<T>> buckets = new ArrayList<>(numberOfBuckets);
|
||||||
for (int i = 0; i < numberOfBuckets; ++i) {
|
for (int i = 0; i < numberOfBuckets; i++) {
|
||||||
buckets.add(new ArrayList<>());
|
buckets.add(new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
return buckets;
|
||||||
/* store elements to buckets */
|
|
||||||
for (int value : arr) {
|
|
||||||
int hash = hash(value, min, numberOfBuckets);
|
|
||||||
buckets.get(hash).add(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sort individual bucket */
|
/**
|
||||||
for (List<Integer> bucket : buckets) {
|
* Distributes elements from the array into the appropriate buckets.
|
||||||
Collections.sort(bucket);
|
*
|
||||||
|
* @param array the array of elements to distribute
|
||||||
|
* @param buckets the list of buckets
|
||||||
|
* @param min the minimum value in the array
|
||||||
|
* @param max the maximum value in the array
|
||||||
|
* @param numberOfBuckets the total number of buckets
|
||||||
|
* @param <T> the type of elements in the array
|
||||||
|
*/
|
||||||
|
private <T extends Comparable<T>> void distributeElementsIntoBuckets(T[] array, List<List<T>> buckets, final T min, final T max, final int numberOfBuckets) {
|
||||||
|
for (final T element : array) {
|
||||||
|
int bucketIndex = hash(element, min, max, numberOfBuckets);
|
||||||
|
buckets.get(bucketIndex).add(element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* concatenate buckets to origin array */
|
/**
|
||||||
|
* Concatenates the sorted buckets back into the original array.
|
||||||
|
*
|
||||||
|
* @param buckets the list of sorted buckets
|
||||||
|
* @param array the original array
|
||||||
|
* @param <T> the type of elements in the array
|
||||||
|
* @return the sorted array
|
||||||
|
*/
|
||||||
|
private <T extends Comparable<T>> T[] concatenateBuckets(List<List<T>> buckets, T[] array) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (List<Integer> bucket : buckets) {
|
for (List<T> bucket : buckets) {
|
||||||
for (int value : bucket) {
|
Collections.sort(bucket);
|
||||||
arr[index++] = value;
|
for (T element : bucket) {
|
||||||
|
array[index++] = element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return array;
|
||||||
return arr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get index of bucket which of our elements gets placed into it.
|
* The method computes the index of the bucket in which a given element should be placed.
|
||||||
|
* This is done by "normalizing" the element within the range of the array's minimum (min) and maximum (max) values,
|
||||||
|
* and then mapping this normalized value to a specific bucket index.
|
||||||
*
|
*
|
||||||
* @param elem the element of array to be sorted
|
* @param element the element of the array
|
||||||
* @param min min value of array
|
* @param min the minimum value in the array
|
||||||
* @param numberOfBucket the number of bucket
|
* @param max the maximum value in the array
|
||||||
* @return index of bucket
|
* @param numberOfBuckets the total number of buckets
|
||||||
|
* @param <T> the type of elements in the array
|
||||||
|
* @return the index of the bucket
|
||||||
*/
|
*/
|
||||||
private static int hash(int elem, int min, int numberOfBucket) {
|
private <T extends Comparable<T>> int hash(final T element, final T min, final T max, final int numberOfBuckets) {
|
||||||
return (elem - min) / numberOfBucket;
|
double range = max.compareTo(min);
|
||||||
|
double normalizedValue = element.compareTo(min) / range;
|
||||||
|
return (int) (normalizedValue * (numberOfBuckets - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private <T extends Comparable<T>> T findMin(T[] array) {
|
||||||
* Calculate max value of array
|
T min = array[0];
|
||||||
*
|
for (T element : array) {
|
||||||
* @param arr the array contains elements
|
if (element.compareTo(min) < 0) {
|
||||||
* @return max value of given array
|
min = element;
|
||||||
*/
|
|
||||||
public static int max(int[] arr) {
|
|
||||||
int max = arr[0];
|
|
||||||
for (int value : arr) {
|
|
||||||
if (value > max) {
|
|
||||||
max = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate min value of array
|
|
||||||
*
|
|
||||||
* @param arr the array contains elements
|
|
||||||
* @return min value of given array
|
|
||||||
*/
|
|
||||||
public static int min(int[] arr) {
|
|
||||||
int min = arr[0];
|
|
||||||
for (int value : arr) {
|
|
||||||
if (value < min) {
|
|
||||||
min = value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T extends Comparable<T>> T findMax(T[] array) {
|
||||||
|
T max = array[0];
|
||||||
|
for (T element : array) {
|
||||||
|
if (element.compareTo(max) > 0) {
|
||||||
|
max = element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,48 +1,8 @@
|
|||||||
package com.thealgorithms.sorts;
|
package com.thealgorithms.sorts;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
public class BucketSortTest extends SortingAlgorithmTest {
|
||||||
|
@Override
|
||||||
import org.junit.jupiter.api.Test;
|
SortAlgorithm getSortAlgorithm() {
|
||||||
|
return new BucketSort();
|
||||||
public class BucketSortTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void bucketSortSingleIntegerArray() {
|
|
||||||
int[] inputArray = {4};
|
|
||||||
int[] outputArray = BucketSort.bucketSort(inputArray);
|
|
||||||
int[] expectedOutput = {4};
|
|
||||||
assertArrayEquals(outputArray, expectedOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void bucketSortNonDuplicateIntegerArray() {
|
|
||||||
int[] inputArray = {6, 1, 99, 27, 15, 23, 36};
|
|
||||||
int[] outputArray = BucketSort.bucketSort(inputArray);
|
|
||||||
int[] expectedOutput = {1, 6, 15, 23, 27, 36, 99};
|
|
||||||
assertArrayEquals(outputArray, expectedOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void bucketSortDuplicateIntegerArray() {
|
|
||||||
int[] inputArray = {6, 1, 27, 15, 23, 27, 36, 23};
|
|
||||||
int[] outputArray = BucketSort.bucketSort(inputArray);
|
|
||||||
int[] expectedOutput = {1, 6, 15, 23, 23, 27, 27, 36};
|
|
||||||
assertArrayEquals(outputArray, expectedOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void bucketSortNonDuplicateIntegerArrayWithNegativeNum() {
|
|
||||||
int[] inputArray = {6, -1, 99, 27, -15, 23, -36};
|
|
||||||
int[] outputArray = BucketSort.bucketSort(inputArray);
|
|
||||||
int[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99};
|
|
||||||
assertArrayEquals(outputArray, expectedOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void bucketSortDuplicateIntegerArrayWithNegativeNum() {
|
|
||||||
int[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23};
|
|
||||||
int[] outputArray = BucketSort.bucketSort(inputArray);
|
|
||||||
int[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27};
|
|
||||||
assertArrayEquals(outputArray, expectedOutput);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user