【问题标题】:How do I modify my Quick Sort Algorithm so that it can sort Double data type arrays?如何修改我的快速排序算法,以便它可以对 Double 数据类型数组进行排序?
【发布时间】:2017-10-03 06:41:45
【问题描述】:

我使用这种快速排序算法对整数数组进行排序,但我也希望它对双精度数组进行排序。我需要更改哪些变量才能完成这项工作?我尝试更改许多不同的数据类型组合。

感谢任何帮助。

       static void Main(string[] args)
    {

     double[] myArray_3 = { 25.1573, 5.1437, 8.1421, 3.1625, 12.3187, 2.8465, 78.0454, -32.6666, -
     51.9204, -31.9391, -30.6136, -12.1411, -4.7172, -6.1189, 15.1574, 10.8995, 21.0344, 49.7912};
     double[] myArray_4 = {-56.6149, -27.4997, 17.1503, -1.5368, -31.3245, -17.5386, 6.9865, -27.8045,
     27.2986, -17.9399, 50.6482, -30.2363, 5.5773, -42.5887, -20.2617, -16.6110, 11.2374,
     26.3797, 8.4136, -10.4460, 22.8337, 22.3688, 3.3657, 15.9949, 11.5583, -27.6349, 21.2679, -
     18.4016, -16.9097, 4.9545, -8.6101, -3.6910};

        QuickSort(myArray_3);

        foreach (int item in myArray_3)
        {
            Console.WriteLine(item);
        }

    }
    public static void QuickSort(int[] data)
    {
        Quick_Sort(data, 0, data.Length - 1);
    }

    public static void Quick_Sort(int[] data, int left, int right)
    {
        int i, j;
        int pivot, temp;
        i = left;
        j = right;
        pivot = data[(left + right) / 2];
        do
        {
            while ((data[i] < pivot) && (i < right)) i++;
            while ((pivot < data[j]) && (j > left)) j--;
            if (i <= j)
            {
                temp = data[i];
                data[i] = data[j];
                data[j] = temp;
                i++;
                j--;
            }
        } while (i <= j);
        if (left < j) Quick_Sort(data, left, j);
        if (i < right) Quick_Sort(data, i, right);
    }

【问题讨论】:

  • 您可以考虑将Quick_Sort() 设为具有IComparable&lt;&gt; 类型约束的泛型方法。例如public static void Quick_Sort&lt;T&gt;(T[] data, int left, int right) where T : IComparable&lt;T&gt; { ... } 然后您可以使用 data[i].CompareTo(pivot) 或其他代替 &lt;&gt; 运算符。 ints 和 doubles 都实现了IComparable&lt;&gt;,因此它适用于这两者,以及实现该接口的任何其他东西。

标签: c# arrays algorithm sorting quicksort


【解决方案1】:

您应该能够使用泛型,其中类型实现了IComparable&lt;T&gt;,以便您可以比较项目(您不能在泛型类型上使用&lt;&gt; 运算符)。

这应该可以解决问题:

public static void QuickSort<T>(T[] data) where T:IComparable<T>
{
    Quick_Sort(data, 0, data.Length - 1);
}

public static void Quick_Sort<T>(T[] data, int left, int right) where T:IComparable<T>
{
    int i, j;
    T pivot, temp;
    i = left;
    j = right;
    pivot = data[(left + right) / 2];

    do
    {
        while ((data[i].CompareTo(pivot) < 0) && (i < right)) i++;
        while ((pivot.CompareTo(data[j]) < 0) && (j > left)) j--;
        if (i <= j)
        {
            temp = data[i];
            data[i] = data[j];
            data[j] = temp;
            i++;
            j--;
        }
    } while (i <= j);

    if (left < j) Quick_Sort(data, left, j);
    if (i < right) Quick_Sort(data, i, right);
}

【讨论】:

  • 而且我看到 itsme86 基本上在 cmets 中徒手写出了答案,所用时间比我在 Visual Studio 中修改您的代码要短。干得好!
  • 谢谢,解决了我的问题 ^^ 排序正确,但现在不显示带有十进制值的数字,如何打印出所有 4 个小数位的数字数组? (是的,我是菜鸟)。
  • 好吧,在您的foreach 代码中,您将所有项目从double 转换为int。不要那样做。 :) 应该是:foreach (double item in myArray_3)
  • Facepalm 哈哈,我犯了这么愚蠢的错误......再次感谢
  • 等号运算符对于双精度数并不那么简单。您需要与浮点 epsilon 进行比较。
【解决方案2】:

不管你决定做什么:


安全地使用浮点数

定义双精度浮点数相等的可靠方法不是operator==。它是:

(a - b &lt; Double.Epsilon)


专门针对快速排序

快速排序起初看起来很简单,但有很多陷阱。第一个是它具有可以是二次方的最坏情况性能。如果您想推出自己的快速排序,您需要了解如何缓解这些情况:

  1. 在排序之前对数组进行洗牌。这是保证性能所必需的。具体来说,Hoare 分区方案(快速排序的原始分区方案)在数组呈现特定顺序时会降低性能。

  2. 请记住,快速排序不是一种稳定的排序算法。这意味着您不能按多个条件进行排序,因为在嵌套排序中不会保留顺序。

  3. 荷兰国旗问题。如果您允许重复值,您最终可能会得到一个胖分区,这将使快速排序在二次时间中运行 (O(n^2))。这可以通过快速排序变体(如 3 向快速排序)来解决。

【讨论】:

  • epsilon 问题在这里不合适。我们绝对确实希望在排序时严格比较我们的值。我们希望 epsilon、2*epsilon、3*epsilon 都被视为不同
  • @AakashM:更重要的是,质量问题在这里是不合适的,因为在排序时我们总是使用比较,而不是相等检查。此外,这个答案的内容虽然对于那些想了解更多关于快速排序的人来说可能很有趣,但与我如何将其转换为双精度而不是整数的问题无关。
  • 如果您想在某个时间点进行精确比较,但可以肯定的是,这一点是正确的。不等式运算符很好。请记住,无论如何在处理浮点数时,都没有坏处:)
  • @partycoder 感谢您提到先对数组进行洗牌。我必须使用的数组有很多排序,例如按顺序排列 20 个同名元素。但是如何洗牌呢?我还读到另一种方法是选择一个随机枢轴以最小化最坏情况下的性能,但找不到任何如何完成的示例
  • @IllimarIssak 您可以使用具有时间复杂度的 Fisher-Yates(又名 Knuth shuffle)实现O(n)
猜你喜欢
  • 2012-07-12
  • 2016-09-25
  • 2017-10-03
  • 2010-11-03
  • 2020-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多