Jar recommendation for collections and sorting (merge sort)
I need a recommendation for a good implementation of merge sort in Java. Basically, I can write all the merges but if I would have a good jar from a provider such as Apache or Google it would be nicer.
Requirements for the merge sort:
- I get an unknown number of sorted arrays.
- Very important: I get a number that says when to stop (lets say it says 34 on a random incident - I want my algorithm to stop sorting when it reaches tha开发者_如何学Got number).
No need to write the code here, I'm only looking for an available jar/library.
I don't know of a ready-made solution, but it appears simple enough to implement with the help of a priority queue:
import static java.util.Arrays.asList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.PriorityQueue;
public class MergingIterator<T> implements Iterator<T> {
public static class InputIter<T> {
final Iterator<T> source;
T data;
public InputIter(Iterable<T> list) {
source = list.iterator();
read();
}
public void read() {
if (source.hasNext()) {
data = source.next();
} else {
data = null;
}
}
}
final PriorityQueue<InputIter<T>> queue;
public MergingIterator(final Comparator<? super T> cmp, Iterable<T>... lists) {
queue = new PriorityQueue<InputIter<T>>(lists.length, new Comparator<InputIter<T>>() {
@Override
public int compare(InputIter<T> o1, InputIter<T> o2) {
return cmp.compare(o1.data, o2.data);
}
});
for (Iterable<T> list : lists) {
InputIter<T> ii = new InputIter<T>(list);
if (ii.data != null) {
queue.add(ii);
}
}
}
@Override
public boolean hasNext() {
return !queue.isEmpty();
}
@Override
public T next() {
InputIter<T> ii = queue.poll();
T next = ii.data;
ii.read();
if (ii.data != null) {
queue.add(ii);
}
return next;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
Test code:
Comparator<Integer> cmp = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
};
List<Integer> empty = asList();
Iterator<Integer> iter = new MergingIterator<Integer> (
cmp,
asList(1, 2, 4, 5, 7, 8),
asList(3),
asList(6, 9),
asList(0),
empty
);
while (iter.hasNext()) {
System.out.println(iter.next());
}
The space complexity is O(L), and the time complexity is O((L + K) log(L)) where L is the number of lists, and K the number of retrieved elements.
This is pretty specialized to find it in general purpose library..... Not hard to implement it yourself.
http://www.docjar.com/html/api/java/util/Collections.java.html
1944 @SuppressWarnings("unchecked")
1945 public static <T extends Comparable<? super T>> void sort(List<T> list) {
1946 Object[] array = list.toArray();
1947 Arrays.sort(array);
1948 int i = 0;
1949 ListIterator<T> it = list.listIterator();
1950 while (it.hasNext()) {
1951 it.next();
1952 it.set((T) array[i++]);
1953 }
1954 }
and here are implementations of sorting arrays:
http://www.docjar.com/html/api/java/util/Arrays.java.html
2588 public static void sort(Object[] array) {
2589 sort(0, array.length, array);
2590 }
2620 private static void sort(int start, int end, Object[] array) {
2621 int length = end - start;
2622 if (length <= 0) {
2623 return;
2624 }
2625 if (array instanceof String[]) {
2626 stableStringSort((String[]) array, start, end);
2627 } else {
2628 Object[] out = new Object[end];
2629 System.arraycopy(array, start, out, start, length);
2630 mergeSort(out, array, start, end);
2631 }
2632 }
2666 @SuppressWarnings("unchecked")
2667 private static void mergeSort(Object[] in, Object[] out, int start,
2668 int end) {
2669 int len = end - start;
2670 // use insertion sort for small arrays
2671 if (len <= SIMPLE_LENGTH) {
2672 for (int i = start + 1; i < end; i++) {
2673 Comparable<Object> current = (Comparable<Object>) out[i];
2674 Object prev = out[i - 1];
2675 if (current.compareTo(prev) < 0) {
2676 int j = i;
2677 do {
2678 out[j--] = prev;
2679 } while (j > start
2680 && current.compareTo(prev = out[j - 1]) < 0);
2681 out[j] = current;
2682 }
2683 }
2684 return;
2685 }
2686 int med = (end + start) >>> 1;
2687 mergeSort(out, in, start, med);
2688 mergeSort(out, in, med, end);
2689
2690 // merging
2691
2692 // if arrays are already sorted - no merge
2693 if (((Comparable<Object>) in[med - 1]).compareTo(in[med]) <= 0) {
2694 System.arraycopy(in, start, out, start, len);
2695 return;
2696 }
2697 int r = med, i = start;
2698
2699 // use merging with exponential search
2700 do {
2701 Comparable<Object> fromVal = (Comparable<Object>) in[start];
2702 Comparable<Object> rVal = (Comparable<Object>) in[r];
2703 if (fromVal.compareTo(rVal) <= 0) {
2704 int l_1 = find(in, rVal, -1, start + 1, med - 1);
2705 int toCopy = l_1 - start + 1;
2706 System.arraycopy(in, start, out, i, toCopy);
2707 i += toCopy;
2708 out[i++] = rVal;
2709 r++;
2710 start = l_1 + 1;
2711 } else {
2712 int r_1 = find(in, fromVal, 0, r + 1, end - 1);
2713 int toCopy = r_1 - r + 1;
2714 System.arraycopy(in, r, out, i, toCopy);
2715 i += toCopy;
2716 out[i++] = fromVal;
2717 start++;
2718 r = r_1 + 1;
2719 }
2720 } while ((end - r) > 0 && (med - start) > 0);
2721
2722 // copy rest of array
2723 if ((end - r) <= 0) {
2724 System.arraycopy(in, start, out, i, med - start);
2725 } else {
2726 System.arraycopy(in, r, out, i, end - r);
2727 }
2728 }
hope it helps :)
精彩评论