简体   繁体   English

快速排序算法(C#)

[英]Quicksort algorithm (C#)

I would like to ask what's actually wrong on this code. 我想问一下这段代码实际上有什么问题。 I tried to understand quicksort (2-way) by myself so I looked into this page: http://me.dt.in.th/page/Quicksort/#disqus_thread after that I tried to code it by myself and landed here: 我试图自己理解quicksort(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);
    }

Then I looked into the comments on the mentioned website and found this: 然后,我调查了提到的网站上的评论,发现了这一点:

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);
}

and now I'm really curious why my code is still working, tested it with this (it's included in a linked list by the way): 现在我真的很好奇为什么我的代码仍然可以正常工作,对此进行了测试(顺便说一句,它包含在链接列表中):

    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);
    }

and this: 和这个:

    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;
    }

and this: 和这个:

    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;
    }

Your quicksort code is not really quicksort, and it will be slow. 您的quicksort代码不是真正的quicksort,它会很慢。 The line 线

        Sort(del, l, l - 1);

will not do anything, since the recursed into call will detect l >= (l-1). 不会执行任何操作,因为递归调用会检测到l> =(l-1)。 The line 线

        Sort(del, l + 1, r);

only reduces the size of the partition [l,r] by one to [l+1,r], so the time complexity will always be O(n^2), but it looks like it will work, just slowly. 仅将分区[l,r]的大小减小1到[l + 1,r],所以时间复杂度将始终为O(n ^ 2),但看起来它将起作用,只是速度很慢。

The qsort() function swaps the left and middle values, this will avoid worst case issue if data is already sorted, but doesn't do much else. qsort()函数交换左值和中间值,如果已对数据进行排序,但不会做其他很多事情,这将避免最坏情况的问题。 The key is that it updates "last", so that when partition is completed, the value at v[last] will be the pivot value, and then it makes recursive calls using "last" instead of "left" or in your code's case, "l". 关键是它会更新“ last”,以便在分区完成后,v [last]处的值将成为枢轴值,然后使用“ last”而不是“ left”或在您的代码中进行递归调用,“ l”。

The qsort shown is a variation of Lomuto partition scheme. 所示的qsort是Lomuto分区方案的变体。 Take a look at the wiki article which also includes the alternate Hoare partition scheme: 看一下Wiki文章,其中还包括备用的Hoare分区方案:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM