【问题标题】:Quicksort algorithm (C#)快速排序算法 (C#)
【发布时间】:2018-05-17 04:06:18
【问题描述】:

我想问一下这段代码到底有什么问题。我试图自己理解快速排序(2-way),所以我查看了这个页面:http://me.dt.in.th/page/Quicksort/#disqus_thread 之后我尝试自己编写代码并登陆这里:

    public void Sort(Comparison<TList> del, long l, long r)
    {
        // inspired by: http://me.dt.in.th/page/Quicksort/
        if (l >= r) return;

        // partitioning
        for(long i = l + 1; i <= r; i++)
        {
            if (del.Invoke(this[i], this[l]) < 0)
            {
                Swap(i, l);
            }
        }

        // recursion
        Sort(del, l, l - 1);
        Sort(del, l + 1, r);
    }

然后我查看了上述网站上的 cmets,发现:

void qsort(char *v[], int left, int right)
{
    int i, last;
    void swap(char *v[], int i, int j);

    if (left >= right)
        return;
    swap(v, left, (left + right) / 2);

    last = left;

    for (i = left + 1; i <= right; i++)
        if (strcmp(v[i], v[left]) < 0)
            swap(v, ++last, i);
    swap(v, left, last);
    qsort(v, left, last - 1);
    qsort(v, last + 1, right);
}

现在我真的很好奇为什么我的代码仍然可以工作,用这个对其进行了测试(顺便说一下,它包含在一个链表中):

    static void Main(string[] args)
    {
        MyList<int> obj;

        do
        {
            obj = MyList.Random(100, 0, 100);
            obj.Sort(stdc);
            obj.Sort(stdc);
        } while (obj.IsSorted(stdc));

        Log("Not sorted", obj);

        Console.ReadKey(true);
    }

还有这个:

    public bool IsSorted(Comparison<TList> del)
    {
        var el = start;

        if (el != null)
        {
            while (el.Next != null)
            {
                if (del.Invoke(el.Value, el.Next.Value) > 0) // eq. to this[i] > this[i + 1]
                    return false;
                el = el.Next;
            }
        }

        return true;
    }

还有这个:

    public static MyList<int> Random(int num, int min = 0, int max = 1)
    {
        var res = new MyList<int>();
        var rand = new Random();

        while (num > 0)
        {
            res.Add(rand.Next(min, max));
            num--;
        }

        return res;
    }

【问题讨论】:

  • 您遇到了什么问题?不要只是转储一堆代码并问“这有什么问题?”

标签: c# sorting quicksort


【解决方案1】:

您的快速排序代码并不是真正的快速排序,而且速度会很慢。线

        Sort(del, l, l - 1);

不会做任何事情,因为递归调用会检测到 l >= (l-1)。线

        Sort(del, l + 1, r);

只是将分区[l,r]的大小减一到[l+1,r],所以时间复杂度会一直是O(n^2),不过看起来好像行得通,只是慢慢来.

qsort() 函数交换左值和中间值,如果数据已经排序,这将避免最坏的情况问题,但不会做太多其他事情。关键是它会更新“last”,因此当分区完成时,v[last] 处的值将是主值,然后它使用“last”而不是“left”或在您的代码的情况下进行递归调用, "l"。

所示的 qsort 是 Lomuto 分区方案的一种变体。查看 wiki 文章,其中还包括备用 Hoare 分区方案:

https://en.wikipedia.org/wiki/Quicksort#Algorithm

【讨论】:

  • 我仍然很好奇它为什么要排序。但是,是的,我明白你为什么它不会做任何事情。
  • 现在翻译得很好...久违了;如果 (l >= r) 返回;交换(l, (l + r) / 2);最后 = l; for (i = l + 1; i
  • 好吧,我想了解该算法,而不仅仅是复制/粘贴它……这就是我开始编写自己的链表的原因……
  • @MarIno - 第一个代码示例有效的原因是它最终将最小元素交换到 this[l] 中,然后对 [l+1, r] 进行递归调用,从而交换将下一个最小值放入 this[l+1],以此类推,直到最后一次交换将下一个最大值放入 this[r-1],最大值最终放入 this[r]。
  • @MarIno - 我建议使用我在答案中链接到的 Wiki 算法。 wiki 文章包含对每种算法的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-24
  • 1970-01-01
  • 2014-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多