【问题标题】:Can anyone help tell me why my MergeSort won't sort a list?谁能帮我告诉我为什么我的 MergeSort 不会对列表进行排序?
【发布时间】:2013-10-25 18:40:48
【问题描述】:

在让我的合并排序工作时遇到一些问题。如果有人可以帮助我,我将不胜感激。

我不知道为什么,但是排序出来的列表没有排序。我尝试过使用断点,但这似乎无助于找到问题。

static class MergeSort
{
    //Sort<T> - The <T> is called a generic parameter
    public static IList<T> Sort<T>(IList<T> input)
    {
        List<T> Result = new List<T>();
        Queue<T> Left = new Queue<T>(); //Switched from lists to queues because removing at index 0 is more efficient
        Queue<T> Right = new Queue<T>();
        //Dequeue() and Count() have a time complexity of O(1)

        if (input.Count <= 1)
            return input;

        int midpoint = input.Count / 2;

        for (int i = 0; i < midpoint; i++)
            Left.Enqueue(input[i]);
        for (int i = midpoint; i < input.Count; i++)
            Right.Enqueue(input[i]);

        Left = new Queue<T>(Sort(Left.ToList())); //Recursion! :o
        Right = new Queue<T>(Sort(Right.ToList())); ; //This line and the one above split the list into smaller lists (left and right)

        Result = Merge(Left, Right); //This joins the lists together

        return Result;
    }

    private static List<T> Merge<T>(Queue<T> Left, Queue<T> Right)
    {
        List<T> Result = new List<T>();
        while (Left.Count /* O(1) operation */ > 0 && Right.Count > 0)
        {
            int cmp = Comparison((Left.Peek() as Entity), (Right.Peek() as Entity));
            //If cmp is less than 0, left is less. If it is greater, left is greater

            if (cmp < 0)
                Result.Add(Left.Dequeue());
            //Left.RemoveAt(0) - Using a list to remove at a certain point is inefficient
            else
                Result.Add(Right.Dequeue());
        }

        while (Left.Count > 0)
            Result.Add(Left.Dequeue());

        while (Right.Count > 0)
            Result.Add(Right.Dequeue());

        return Result;
    }

    private static int Comparison(Entity Left, Entity Right)
    {
        if (Left.TimesEaten > Right.TimesEaten)
        {
            return 1;
        }
        else
        {
            return -1;
        }
    }
}

如果你需要知道,在“比较”方法中,Left.TimesEaten 是一个整数。

【问题讨论】:

    标签: c# sorting comparison mergesort


    【解决方案1】:

    Merge 实现中存在错误。对于给定的一对Left 和Right 队列,您只比较它们的first 元素。您实际上需要在每次添加后重新执行比较(例如,通过在循环中移动 Comparison 调用):

    private static List<T> Merge<T>(Queue<T> Left, Queue<T> Right)
    {
        List<T> Result = new List<T>();
        while (Left.Count > 0 && Right.Count > 0)
        {
            int cmp = Comparison((Left.Peek() as Entity), (Right.Peek() as Entity));
            //If cmp is less than 0, left is less. If it is greater, left is greater
    
            if (cmp < 0)
                Result.Add(Left.Dequeue());
            else
                Result.Add(Right.Dequeue());
        }
    
        // ...
    

    【讨论】:

    • 非常感谢您的帮助,这是我的愚蠢错误。仍然得到与问题相同的结果?谢谢
    • 在我的工作正常。您能给我们提供您正在使用的Entity 实例的样本吗?
    • 另外,请确保您正在检查 returned 列表。原始列表未修改。
    • 刚刚意识到我在判断它是否在列表顶部而不是底部有效。我正在阅读最低值,但认为它是最高值。它有效,对不起,我只是一个白痴!非常感谢:D
    【解决方案2】:

    与

    的那一行
    int cmp = Comparison((Left.Peek() as Entity), (Right.Peek() as Entity));
    

    必须在 while 循环内。整个合并使用相同比较的结果。

    【讨论】:

      猜你喜欢
      • 2016-12-26
      • 2010-12-12
      • 1970-01-01
      • 2017-10-09
      • 1970-01-01
      • 1970-01-01
      • 2016-04-25
      • 2022-12-11
      • 1970-01-01
      相关资源
      最近更新 更多