【问题标题】:C# QuickSort recursive program not sortingC# QuickSort 递归程序不排序
【发布时间】:2012-10-08 18:04:43
【问题描述】:

我试图理解一个快速排序的例子。我随机生成 9 个数字并放在一个列表中。程序选择一个随机枢轴。基于枢轴,列表中的其他值被放置到左列表或右列表中。然后我使用左列表和右列表再次调用该方法。这就是我感到困惑的地方。它没有对 9 个数字进行完全排序。我做错了什么?

这是我更新的代码。现在,如果一个枢轴数字与列表中的另一个数字相同,则返回时它不包含在排序列表中,例如未排序的 487878146,排序的 14678 我认为导致问题的代码是 (if (j == pivot) continue;)

public static List<int> QuickSort(List<int> arr)
    {
        Random random = new Random();
        int i, pivot;

        List<int> leftList = new List<int>();
        List<int> rightList = new List<int>();

        if (arr.Count > 1)
        {
            //pivot = random.Next(arr[0],arr[arr.Count - 1]);
            pivot = arr[random.Next(0, arr.Count - 1)];
                foreach(int j in arr)
                {
                    if (j == pivot) continue;
                    if (j <= pivot)
                        leftList.Add(j);
                    else
                        rightList.Add(j);
                }

            List<int> sortedLeft = QuickSort(leftList);
            List<int> sortedRight = QuickSort(rightList);

            List<int> tempList = new List<int>();
            tempList.AddRange(sortedLeft);
            tempList.Add(pivot);
            tempList.AddRange(sortedRight);

            //for (i = 1; i <= leftList.Count; i++)
            //    tempList.Add(leftList[i - 1]);
            //tempList.Add(pivot);
            //for (i = 1; i <= rightList.Count; i++)
            //    tempList.Add(rightList[i - 1]);


            return tempList;
        }
        return arr;
    }

【问题讨论】:

  • 您不应创建多个 Random 对象。创建一个并重用它。虽然在这里它可能与您的实际问题无关。
  • 请先自己调试你的代码...今天早些时候也有相同问题的解决方案可以比较 - stackoverflow.com/questions/12785824/…
  • 这看起来根本不像快速排序。这看起来像合并排序,但没有合并,并且没有将每个段完全切成两半。
  • 另外,快速排序的优点之一不是能够就地排序,而不是使用临时列表吗?
  • 您选择的枢轴并不总是列表中的一个项目。而不是 max 和 min 之间的随机数,取 0 和列表大小之间的随机索引并使用该索引处的项目。 (或者,为简单起见,只使用第一项)。

标签: c# wpf arrays collections quicksort


【解决方案1】:

您的快速排序返回排序后的列表,因此您需要合并它们而不是未排序的输入:

List<int> sortedLeft = QuickSort(leftList);
List<int> sortedRight QuickSort(rightList);

List<int> tempList = new List<int>();
tempList.AddRange(sortedLeft);
tempList.Add(pivot);
tempList.AddRange(sortedRight);

【讨论】:

    【解决方案2】:

    除了 Lee 的回答之外,您还应该修改您的枢轴选择,因为您使用的随机数不必在数组中,然后将其插入到列表中。例如,您可以尝试这样的事情:

    pivot = arr[random.Next(0,arr.Length - 1)];
    

    【讨论】:

    • 谢谢,我更新了我的代码。现在,如果一个枢轴数字与列表中的另一个数字相同,则返回时它不会包含在排序列表中,例如未排序 487878146,已排序 14678 我认为导致问题的代码是(如果(j == pivot)继续;)
    • 是的,但是您可以在任何您想要的列表中包含 j 元素。例如,不要继续,而是放入一个 leftList。
    • 我尝试了 StackOverflow 异常。我所做的是计算 j 元素等于枢轴的次数。然后,当我合并列表时,我会根据计数向列表添加 n 次枢轴。它有效。
    猜你喜欢
    • 2015-05-26
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    • 2021-03-22
    • 2020-12-31
    • 2022-01-11
    • 2013-03-15
    • 1970-01-01
    相关资源
    最近更新 更多