2.3.16

2.3.16 #

解答 #

官方实现见:https://algs4.cs.princeton.edu/23quicksort/QuickBest.java.html

类似于快速排序的结构,只要中点的两边都是最佳情况,那么整个数组就是最佳情况了。

具体方法是:

首先构造一个有序数组,

然后找到中点(作为枢轴),

对中点左右两侧子数组进行构造,

将选择的枢轴放到开始处(a[lo])。

代码 #

用于构造最佳数组的类。

public class QuickBest
{
    /// <summary>
    /// 构造函数,这个类不应该被实例化。
    /// </summary>
    private QuickBest() { }

    /// <summary>
    /// 构造适用于快速排序的最佳数组。
    /// </summary>
    /// <param name="n">数组长度。</param>
    /// <returns>适用于快速排序的最佳情况数组。</returns>
    public static int[] Best(int n)
    {
        var a = new int[n];
        for (var i = 0; i < n; i++)
        {
            a[i] = i;
        }
        Best(a, 0, n - 1);
        return a;
    }

    /// <summary>
    /// 递归的构造数组。
    /// </summary>
    /// <param name="a">需要构造的数组。</param>
    /// <param name="lo">构造的起始下标。</param>
    /// <param name="hi">构造的终止下标。</param>
    private static void Best(int[] a, int lo, int hi)
    {
        if (hi <= lo)
            return;
        var mid = lo + (hi - lo) / 2;
        Best(a, lo, mid - 1);
        Best(a, mid + 1, hi);
        Exch(a, lo, mid);
    }

    /// <summary>
    /// 交换数组中的两个元素。
    /// </summary>
    /// <param name="a">包含要交换元素的数组。</param>
    /// <param name="x">需要交换的第一个元素下标。</param>
    /// <param name="y">需要交换的第二个元素下标。</param>
    private static void Exch(int[] a, int x, int y)
    {
        var t = a[x];
        a[x] = a[y];
        a[y] = t;
    }
}

用于测试的方法

var quick = new QuickSortAnalyze
{
    NeedShuffle = false, // 关闭打乱
    NeedPath = true // 显示排序轨迹
};
var a = QuickBest.Best(10);
for (var i = 0; i < 10; i++)
{
    Console.Write(a[i] + " ");
}

Console.WriteLine();
quick.Sort(a);
for (var i = 0; i < 10; i++)
{
    Console.Write(a[i] + " ");
}

Console.WriteLine();

另请参阅 #

Quick 库