我需要一個良好的執行Java中合併排序的建議。 基本上,我可以寫所有的合併,但如果我必須從供應商如Apache或谷歌的好罐子還要好。罐推薦和排序(排序合併)
的合併排序要求:
- 我得到一個未知數量的排序陣列。
- 非常重要:我得到一個數字說明什麼時候停止(讓我們說在一個隨機事件中說34) - 我希望我的算法在達到該數字時停止排序)。
不需要在這裏寫代碼,我只是在尋找一個可用的jar /庫。
我需要一個良好的執行Java中合併排序的建議。 基本上,我可以寫所有的合併,但如果我必須從供應商如Apache或谷歌的好罐子還要好。罐推薦和排序(排序合併)
的合併排序要求:
不需要在這裏寫代碼,我只是在尋找一個可用的jar /庫。
我不知道一個現成的但是它看起來很簡單,足以實現無線網絡個優先級隊列的幫助下:
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();
}
}
測試代碼:
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());
}
的空間複雜度是O(L),和時間複雜度是O((L + K)的日誌(L) )其中L是列表的數量,K是檢索到的元素的數量。
這是非常專業的找到它的通用庫.....不難實現它自己。
同意。但是,如果要將其擴展到大量(已排序)列表,則不容易編寫。 – 2011-06-05 15:37:48
@Ted _it如果想要縮放,寫起來不是那麼容易_ - 非常真實。他提到_arrays_,如果它們是鏈接列表,而不是修改它們的問題。會很容易。無論如何,有不同的解決方案取決於輸入大小和輸入數據結構的假設。 ....我建議_從Bentley編程珍珠_ – 2011-06-05 16:27:52
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 }
,這裏是數組排序的實現:
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 }
希望它能幫助:)
'Collections.sort()'是歸併 – dantuch 2011-06-05 15:25:42
但只得到一個列表。我可以將所有列表連接到一個大列表並對其進行排序,但它會對整個元素進行排序。我希望能夠控制何時停止排序。謝謝。 – Jeb 2011-06-05 15:29:24
@dantuch他需要在合併期間做事情,並且已經預分類了他想要合併的列表 – 2011-06-05 15:29:37