如何让这个 Dual Pivot Quicksort 变得更好/更快

How can this DualPivot Quicksort be made better / faster

标题已经说过了,我问的是如何使我的代码更快或更好。现在我遇到的问题是我的 Dual Pivot Quicksort 比普通的 Quicksort 慢得多,而且也不能处理大数。现在我只是要输入方法的代码,但如果你愿意,我也可以 post Main 方法,所以你可以看到我的输入。

public static List<int> sort(List<int> input, bool start)
{
    if (input.Count > 1)
    {
        int LP = input[0];
        int RP = input[input.Count - 1];
        List<int> lessLP = new List<int>();
        List<int> greatRP = new List<int>();
        List<int> betweenLPRP = new List<int>();
        if (LP > RP)
        {
            int sp = LP;
            LP = RP;
            RP = sp;
        }

        for (int i = 1; i < input.Count - 1; i++)
        {
            if (input[i] < LP)
            {
                lessLP.Add(input[i]);
            }

            else if (input[i] > RP)
            {
                greatRP.Add(input[i]);
            }

            else if (input[i] >= LP & input[i] <= RP)
            {
                betweenLPRP.Add(input[i]);
            }
        }
        List<int> end = new List<int>();

        lessLP = sort(lessLP, false);
        greatRP = sort(greatRP, false);
        betweenLPRP = sort(betweenLPRP, false);
        input.Clear();

        foreach (var x in lessLP)
        {
            end.Add(x);
        }
        lessLP.Clear();
        end.Add(LP);
        foreach (var x in betweenLPRP)
        {
            end.Add(x);
        }
        betweenLPRP.Clear();
        end.Add(RP);
        foreach (var x in greatRP)
        {
            end.Add(x);
        }
        greatRP.Clear();
        return end;
    }
    return input;
}

感谢您的帮助。 顺便说一句,很抱歉未注释的代码

编辑: 好的,经过一些反馈,我尝试获取此代码 https://cs.stackexchange.com/questions/24092/dual-pivot-quicksort-reference-implementation 作为 c# 工作。

但现在每次我 运行 这段代码都会收到 WhosebugException

        public static void quicksort(ref int[] arr, int left, int right)
        {
            if (right > left)
            {
                if (arr[left] > arr[right]) swap(ref arr, left, right);
                int p = arr[left], q = arr[right];

                int l = left + 1, g = right - 1, k = 1; 
                while(k <= g)
                {
                    if (arr[k] < p)
                    {
                        swap(ref arr, k, l);
                        l++;
                    }

                    else if (arr[k] >= q)
                    {
                        while (arr[g] > q && k < g) g--;
                        swap(ref arr, k, g);
                        g--;
                        if(arr[k] < p)
                        {
                            swap(ref arr, k, l);
                            l++;
                        }
                    }
                    k++;
                }
                l--; g++;

                swap(ref arr, left, l);
                swap(ref arr, right, g);
                quicksort(ref arr, left, l - 1);
                quicksort(ref arr, l + 1, g - 1);
                quicksort(ref arr, g + 1, right);
            }
        }

        public static void swap(ref int[] arr, int i, int j)
        {
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }

您在翻译该参考中的代码时有错别字。

这一行:

int l = left + 1, g = right - 1, k = 1;

您拥有的最后一个 1(一个)应该是 l(小写 L)。

顺便说一句,由于数组在 c# 中定义为引用类型,因此 arr 参数上的 ref 修饰符是不必要的。仅当您希望从方法内(如 arr = new ... 中)替换整个参数并将该更改反映在调用者中时才需要这样做。这适用于 quicksortswap。这里,ref 只会降低代码的效率。

另一个小问题是引用的代码(和你的代码)在调用 swap 时使用相同的 ij 参数时效率低下 - 但不影响有效性, 只有速度。