用比较器和交换函数进行java排序

时间:2011-02-13 11:02:14

标签: java sorting

我需要使用自定义比较器和交换功能对函数进行排序。我可以自己写一个,但我想知道其他人是否还没有这样做。 Java运行时包含许多专门的排序函数,用于排序基本类型,对象等数组,但它们都没有将交换函数作为参数。谷歌搜索也没有找到任何有用的东西。

public interface IntComparator
{
    int compare(int a, int b);
}
public interface IntSwap
{
    void swap(int a, int b);
}
public static void sort(IntComparator compFn, IntSwap swapFn, int off, int len);

5 个答案:

答案 0 :(得分:4)

这就是我要找的东西。它基于java运行时算法对整数进行排序。通过正确实现Sortable接口,它可以对任何事物进行排序。

public class Sort {
    public static void sort(Sortable sortable, int off, int len) {
        // Insertion sort on smallest arrays
        if (len < 7) {
            for (int i = off; i < len + off; i++) {
                for (int j = i; j > off && sortable.compare(j - 1, j) > 0; j--) {
                    sortable.swap(j, j - 1);
                }
            }
            return;
        }

// Choose a partition element, v int m = off + (len >> 1); // Small arrays, middle element if (len > 7) { int l = off; int n = off + len - 1; if (len > 40) { // Big arrays, pseudomedian of 9 int s = len / 8; l = med3(sortable, l, l + s, l + 2 * s); m = med3(sortable, m - s, m, m + s); n = med3(sortable, n - 2 * s, n - s, n); } m = med3(sortable, l, m, n); // Mid-size, med of 3 } // Establish Invariant: v* (<v)* (>v)* v* int a = off, b = a, c = off + len - 1, d = c; while (true) { while (b <= c && sortable.compare(b, m) <= 0) { if (sortable.compare(b, m) == 0) { sortable.swap(a, b); m = a; a++; } b++; } while (c >= b && sortable.compare(c, m) >= 0) { if (sortable.compare(c, m) == 0) { sortable.swap(c, d); m = d; d--; } c--; } if (b > c) { break; } sortable.swap(b++, c--); } // Swap partition elements back to middle int s, n = off + len; s = Math.min(a - off, b - a); vecswap(sortable, off, b - s, s); s = Math.min(d - c, n - d - 1); vecswap(sortable, b, n - s, s); // Recursively sort non-partition-elements if ((s = b - a) > 1) { sort(sortable, off, s); } if ((s = d - c) > 1) { sort(sortable, n - s, s); } } private static int med3(Sortable sortable, int a, int b, int c) { return sortable.compare(a, b) < 0 ? (sortable.compare(b, c) < 0 ? b : sortable.compare(a, c) < 0 ? c : a) : sortable.compare(b, c) > 0 ? b : sortable.compare(a, c) > 0 ? c : a; } private static void vecswap(Sortable sortable, int a, int b, int n) { for (int i = 0; i < n; i++, a++, b++) { sortable.swap(a, b); } }

}

答案 1 :(得分:0)

  

我需要在两个数组中交换索引。我知道我可以对二维数组进行排序,但这会增加所需的内存。

没有。如果我理解正确,它不会导致任何开销。

请记住,Java不会将数组或对象直接存储在变量(或数组!)中。它存储引用。即使从数组引用的每个元素都是40字节大,它也将作为引用存储在数组中。

因此,我建议你使用内置的排序机制。它们不会随机播放大量数据,只会引用参考文献。

答案 2 :(得分:0)

由于Object数组的sort() 稳定,您可以在自定义Comparator中获取有用的信息。这个按String长度排序时计算掉期。

import java.util.Arrays;
import java.util.Comparator;

/** @see http://stackoverflow.com/questions/4983746 */
public class SortTest {

    private static class LengthComparator implements Comparator<String> {

        private int count;

        public int compare(String s1, String s2) {
            int a = s1.length();
            int b = s2.length();
            if (a < b) {
                return -1;
            } else if (a > b) {
                count++;
                return 1;
            } else {
                return 0;
            }
        }
    }

    public static void main(String[] args) throws Exception {
        String[] sa = {"One", "Two", "Three", "Four", "Five"};
        System.out.println(Arrays.toString(sa));
        LengthComparator byLength = new LengthComparator();
        Arrays.sort(sa, byLength);
        System.out.println(Arrays.toString(sa));
        System.out.println(byLength.count);
    }
}

控制台:

[One, Two, Three, Four, Five]
[One, Two, Four, Five, Three]
2

答案 3 :(得分:0)

关于swap:Java按值传递参数,因此方法swap(int a, int b)swap(Object a, Object b)不能按预期工作。

答案 4 :(得分:0)

如果你提出这些接口,至少要对它们应该做的事情添加一些注释。从讨论中我得到了你想要的东西:

/**
 * A Sortable represents a indexed collection of comparable
 * elements.
 * It does not offer direct access to its elements, only
 * comparison and swapping by indices.
 *
 * In the method specifications we are using this[i] to
 * mean the 
 */
public interface Sortable {

    /**
     * Compares two elements by their indices.
     * @return -1 if this[first] < this[second],
     *          0 if this[first] = this[second]
     *          1 if this[first] > this[second]
     * @throws IndexOutOfBoundsException if one
     *      or both indices are outside of the
     *      limits of this sequence.
     */
    public int compare(int first, int second);

    /**
     * Swaps two elements by their indices.
     * This is roughly equivalent to this sequence:
     * <pre>
     *   temp = this[first];
     *   this[first] = this[second];
     *   this[second] = temp;
     * </pre>
     */
    public void swap(int first, int second);

}

interface Sorter {
   /**
    * sorts an interval of a sequence.
    * @param sequence the sequence to be sorted.
    * @param off the start of the interval to be sorted.
    * @param the length of the interval to be sorted.
    */
   public void sort(Sortable sequence, int off, int len);
}

然后你可以让你的排序算法实现Sorter,而你的数据结构实现Sortable。 当然,人们可以在IndexComparatorIndexSwapper中分割Sortable的两个函数(而不是像你命名的Int ......),但它们都直接耦合到你的数据结构(由你的两个组成)阵列)。