This code seems to be a specific BucketSort made for a specific program. I would instead create a more generic BucketSort:
public static <E extends Comparable<E>> void bucketSort(E[] array) {
// ...
}
public static <E> void bucketSort(E[] array, Comparator<E> comparator) {
// ...
}
Note there is two methods; one is for a class that implements the Comparator
interface, and one to allow a Comparator
to be passed as the Comparator
for the class, where there is no comparator, or if you want to compare it in a different way.
Then the only problem is that you don't know the bounds for the buckets; the simple way would be to use bounds provided by the calling method:
public static <E extends Comparable<E>> void bucketSort(E[] array, E[] separators) {
}
public static <E> void bucketSort(E[] array, E[] separators, Comparator<E> comparator) {
}
The separators will be the upper limit of the bucket right before it; and the uppermost bucket will catch everything that is larger than the largest bound.
Now for the actual code:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class BucketSort {
public static <E extends Comparable<E>> List<E> bucketSort(E[] array,
E[] separators) {
Comparator<E> comparator = new Comparator<E>() {
@Override
public int compare(E element1, E element2) {
return element1.compareTo(element2);
}
};
return bucketSort(array, separators, comparator);
}
public static <E> List<E> bucketSort(E[] array, E[] separators,
Comparator<E> comparator) {
final int numOfBuckets = separators.length + 1;
// Create Buckets
// Used ArrayList because we don't need the functions of a LinkedList
List<Bucket<E>> buckets = new ArrayList<Bucket<E>>(numOfBuckets);
for (int i = 0; i < numOfBuckets; i++) {
buckets.add(new Bucket<E>());
}
// Sort into Buckets
for (E element : array) {
// Use binary search
buckets.get(bucketNumber(element, separators, comparator)).getItems().add(element);
}
// Sort buckets
for (Bucket<E> bucket : buckets) {
bucket.getItems().sort(comparator);
}
// Combine Buckets and return
for (int i = 1; i < numOfBuckets; i++) {
buckets.get(0).getItems().addAll(buckets.get(i).getItems());
}
return buckets.get(0).getItems();
}
private static <E> int bucketNumber(E element, E[] separators,
Comparator<E> comparator) {
return bucketNumber(element, separators, 0, separators.length,
comparator);
}
private static <E> int bucketNumber(E element, E[] separators, int low,
int high, Comparator<E> comparator) {
if (low + 1 == high) {
return high;
}
int searchIndex = (high - low) / 2 + low;
int compareResult = comparator
.compare(element, separators[searchIndex]);
if (compareResult == 0) {
return searchIndex;
}
return compareResult < 0 ? bucketNumber(element, separators, low,
searchIndex, comparator) : bucketNumber(element, separators,
searchIndex, high, comparator);
}
}
class Bucket<E> {
private List<E> elements;
public Bucket() {
this.elements = new LinkedList<E>();
}
public Bucket(Collection<E> elements) {
this.elements = new LinkedList<E>(elements);
}
public List<E> getItems() {
return elements;
}
}
Yes, I know it looks 10x more complex than it need to be, but this can be used for further applications.
insertionSortByClass()
? – Manny Meng 1 hour ago