Java 使用非递归排序阈值合并排序

Java 使用非递归排序阈值合并排序,java,algorithm,sorting,Java,Algorithm,Sorting,问题 创建一个程序以对链表执行合并排序 规格 创建一个包含100个范围为1-1000的随机整数的链表 在10 x 10表格中显示未排序的链表。 要使用合并排序例程对链表进行排序,请执行以下操作: 将链表转换为数组 对数组执行递归合并排序 当分区的大小低于某个阈值时,将合并排序算法更改为使用非递归算法(选择排序、插入排序) 在合并排序例程中插入注释,解释选择选择选择排序、插入排序或其他非递归算法的原因,以及如何确定阈值(经验证据) 排序完成后,将数组转换回链表 在10 x 10表格中显示已排序

问题

创建一个程序以对链表执行合并排序

规格

  • 创建一个包含100个范围为1-1000的随机整数的链表
  • 在10 x 10表格中显示未排序的链表。
要使用合并排序例程对链表进行排序,请执行以下操作:

  • 将链表转换为数组
  • 对数组执行递归合并排序
  • 当分区的大小低于某个阈值时,将合并排序算法更改为使用非递归算法(选择排序、插入排序)
  • 在合并排序例程中插入注释,解释选择选择选择排序、插入排序或其他非递归算法的原因,以及如何确定阈值(经验证据)
  • 排序完成后,将数组转换回链表
  • 在10 x 10表格中显示已排序的链表
到目前为止,我的代码是:

public class MergeSort{
    LinkedQueue<Integer> list = new LinkedQueue<Integer>();
    Integer[] a = new Integer[100];

    public MergeSort() {
        for(int i=0; i<100; i++)
        {
            list.enqueue(StdRandom.uniform(999)+1);
        }
    }

    private static boolean less(Comparable v, Comparable w)
    {
        return (v.compareTo(w) < 0);
    }

    private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi)
    {
        for(int k = lo; k <= hi; k++)
            aux[k] = a[k];

        int i = lo, j= mid+1;
        for(int k = lo; k <= hi; k++)
        {
            if (i>mid)
                a[k] = aux[j++];
            else if (j>hi)
                a[k] = aux[i++];
            else if (less(aux[j], aux[i]))
                a[k] = aux[j++];
            else 
                a[k] = aux[i++];
        }
    }

    private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi)
    {
        if((hi-lo) <= 6)
        {
            Comparable[] b = new Comparable[hi-lo];
            for(int i=0; i<b.length; i++)
            {
                b[i] = a[lo+i];
            }
            Selection.sort(b);

            for(int i=0; i<(hi-lo); i++)
            {
                a[lo+i] = b[i];
            }
            return;
        }
        int mid = lo + (hi - lo)/2;
        sort(a, aux, lo, mid);
        sort(a, aux, mid+1, hi);
        merge(a, aux, lo, mid, hi);
    }

    public void sort(Comparable[] a)
    {
        Comparable[] aux = new Comparable[a.length];
        sort(a, aux, 0, a.length-1);
    }

    public static void main(String[] args)
    {
        MergeSort merge = new MergeSort();

        StdOut.println("Unsorted: ");
        for(int i=0; i<10; i++)
        {
            for(int j=0; j<10; j++)
            {
                StdOut.print(merge.list.peek() + " ");
                merge.a[i*10 + j] = merge.list.dequeue();
            }
            StdOut.println();
        }
        StdOut.println();

        merge.sort(merge.a);
        for(int i=0; i<100; i++)
        {
            merge.list.enqueue(merge.a[i]);
        }
        StdOut.println("Sorted: ");
        for(int i=0; i<10; i++)
        {
            for(int j=0; j<10; j++)
            {
                StdOut.print(merge.list.dequeue() + " ");
            }
            StdOut.println();
        }
    }

}   
我相信我已经将问题缩小到递归排序方法的基本情况:

    if((hi-lo) <= 6)
        {
            Comparable[] b = new Comparable[hi-lo];
            for(int i=0; i<b.length; i++)
            {
                b[i] = a[lo+i];
            }
            Selection.sort(b);

            for(int i=0; i<(hi-lo); i++)
            {
                a[lo+i] = b[i];
            }
            return;
        }

if((hi-lo)错误非常简单:
lo
hi
索引都包含在内。这就是为什么它应该是:

if (hi - lo) <= 6) {
    Comparable[] b = new Comparable[hi - lo + 1];
    //                                       ^^^^
    //                                We need plus one here.
    for (int i = 0; i < b.length; i++) {
        b[i] = a[lo + i];
    }
    Selection.sort(b);
    for (int i = 0; i < b.length; i++) {
        //               ^^^^
        //    We should either iterate to hi - lo + 1 or b.length.
        a[lo + i] = b[i];
    }
    return;
}

if(hi-lo)你能显示选择类的源代码吗?在中编辑。请注意,选择类不是我写的。不幸的是,没有运气。仍然会遇到同样的问题。@GraysonErickson你确定吗?我用这个更改测试了它,它工作正常。@GraysonErickson我突出显示了另一个更改(参见编辑)。顺便问一下,你是剪切并粘贴了我答案中提供的代码还是自己做了更改?嗯。你是对的,这似乎确实有效。这很奇怪,因为我很有信心我完全复制了它。但是,是的,复制/粘贴似乎有效。谢谢,克拉斯凯维奇!
import java.util.Comparator;

/**
 *  The <tt>Selection</tt> class provides static methods for sorting an
 *  array using selection sort.
 *  <p>
 *  For additional documentation, see <a href="http://algs4.cs.princeton.edu/21elementary">Section 2.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *  @author Robert Sedgewick
 *  @author Kevin Wayne
 */
public class Selection {

    // This class should not be instantiated.
    private Selection() { }

    /**
     * Rearranges the array in ascending order, using the natural order.
     * @param a the array to be sorted
     */
    public static void sort(Comparable[] a) {
        int N = a.length;
        for (int i = 0; i < N; i++) {
            int min = i;
            for (int j = i+1; j < N; j++) {
                if (less(a[j], a[min])) min = j;
            }
            exch(a, i, min);
            assert isSorted(a, 0, i);
        }
        assert isSorted(a);
    }

    /**
     * Rearranges the array in ascending order, using a comparator.
     * @param a the array
     * @param c the comparator specifying the order
     */
    public static void sort(Object[] a, Comparator c) {
        int N = a.length;
        for (int i = 0; i < N; i++) {
            int min = i;
            for (int j = i+1; j < N; j++) {
                if (less(c, a[j], a[min])) min = j;
            }
            exch(a, i, min);
            assert isSorted(a, c, 0, i);
        }
        assert isSorted(a, c);
    }


   /***********************************************************************
    *  Helper sorting functions
    ***********************************************************************/

    // is v < w ?
    private static boolean less(Comparable v, Comparable w) {
        return (v.compareTo(w) < 0);
    }

    // is v < w ?
    private static boolean less(Comparator c, Object v, Object w) {
        return (c.compare(v, w) < 0);
    }


    // exchange a[i] and a[j]
    private static void exch(Object[] a, int i, int j) {
        Object swap = a[i];
        a[i] = a[j];
        a[j] = swap;
    }


   /***********************************************************************
    *  Check if array is sorted - useful for debugging
    ***********************************************************************/

    // is the array a[] sorted?
    private static boolean isSorted(Comparable[] a) {
        return isSorted(a, 0, a.length - 1);
    }

    // is the array sorted from a[lo] to a[hi]
    private static boolean isSorted(Comparable[] a, int lo, int hi) {
        for (int i = lo + 1; i <= hi; i++)
            if (less(a[i], a[i-1])) return false;
        return true;
    }

    // is the array a[] sorted?
    private static boolean isSorted(Object[] a, Comparator c) {
        return isSorted(a, c, 0, a.length - 1);
    }

    // is the array sorted from a[lo] to a[hi]
    private static boolean isSorted(Object[] a, Comparator c, int lo, int hi) {
        for (int i = lo + 1; i <= hi; i++)
            if (less(c, a[i], a[i-1])) return false;
        return true;
    }



    // print array to standard output
    private static void show(Comparable[] a) {
        for (int i = 0; i < a.length; i++) {
            StdOut.println(a[i]);
        }
    }

    /**
     * Reads in a sequence of strings from standard input; selection sorts them; 
     * and prints them to standard output in ascending order. 
     */
    public static void main(String[] args) {
        String[] a = StdIn.readAllStrings();
        Selection.sort(a);
        show(a);
    }
}
if (hi - lo) <= 6) {
    Comparable[] b = new Comparable[hi - lo + 1];
    //                                       ^^^^
    //                                We need plus one here.
    for (int i = 0; i < b.length; i++) {
        b[i] = a[lo + i];
    }
    Selection.sort(b);
    for (int i = 0; i < b.length; i++) {
        //               ^^^^
        //    We should either iterate to hi - lo + 1 or b.length.
        a[lo + i] = b[i];
    }
    return;
}