实现快速排序算法C#

时间:2017-06-09 15:30:03

标签: c# algorithm quicksort

我正在尝试从头开始实施和构建快速排序算法,我一直在浏览不同的帖子,这似乎是一个热门话题,我不完全确定如何解释其他人用它做了什么让我的工作。

public static void QuickSort(int[] A)
    {
        int i, j, pivot,counter,temp;

        counter = 1;                                    //Sets Initial counter to allow loop to execute
        while (counter != 0)
        {   i = -1;                                     //Left bound
            j = 0;                                      //Right bound
            counter = 0;                                //Count of transpositions per cycle set to zero
            Random rand = new Random();
            pivot = rand.Next(0, A.Length - 1);         //Random Pivot Value Generated

            for (int x = 0; x < A.Length; x++)          //Executes contents for each item in the array
            {                                       
                if (A[pivot] > A[j])                    //Checks if pivot is greater than right bound
                {
                    i++;                                //left bound incremented
                    temp = A[j];                        
                    A[j] = A[i];                    
                    A[i] = temp;                        //swaps left and right bound values
                    j++;                                //Right bound Incremented
                    counter++;                          //Increments number of transpositions for this cycle.
                }
                else j++;                               //else right bound is icremented
            }
                                                        //Heres where it gets sketchy
            temp = A[i+1];                              
            A[i + 1] = A[pivot];                        //pivot value is placed in Index 1+ left bound

            for (int x =(i+2); x <A.Length; x++)        //Shifts the remaining values in the array from index of pivot (1+ left bound) over one position to the end of the array (not functional)
            {
                temp = A[x];
                A[x + 1] = temp;                                       
            }
        }          
    }

正如你所看到的那样,我已经碰到了算法变化部分的问题,而且我真的不确定如何继续而不仅仅是从网络上复制某人的解决方案< / p>

2 个答案:

答案 0 :(得分:1)

第一步 - 实际了解Quicksort中发生的事情......

基本Quicksort算法

  • 从您的项目集合中选择一个(称为数据透视)。 (如何选择它在理论上是无关紧要的,但在实际层面上可能很重要)
  • 将集合中的项目分成两个新集合:小于数据透视的项目和大于数据透视的项目。
  • 分别对两个新集合进行排序(无关紧要 - 大多数实现都是递归调用它们。)
  • 加入现在排序的较低集合,pivot和sort upper集合。

现在,这个特殊的实现有点奇怪。它试图在适当的位置进行,这没关系,但它似乎没有移动枢轴,这意味着它将被覆盖(因此在分区的中间发生变化)

一些挑剔的东西。

  • 不要在循环中间创建新的Random对象。在循环外创建一次,并重用它。这有几个原因。 1)它需要一个(相对)长的时间,2)它以千分之一的时间播种,所以两个在彼此毫秒内创建的两个将创建相同的序列 - 在这里你总是得到相同的轴。

  • 实际上,最好不要使用随机数据。这可能是由对算法的基本误解所启发的。最初,有人建议,因为选择哪个项目作为枢轴无关紧要,你不妨选择第一个项目,因为它最简单。但后来人们发现,已经排序过的集合的最坏情况是以枢轴为中心。所以,他们自然而然地走了另一条路,决定随意转向。那是愚蠢的。对于任何给定的集合,存在导致最坏情况时间的枢轴。通过使用随机枢轴,您可以增加偶然击中它的机会。最佳选择:对于可索引的集合(如数组),最好将物品放在集合的中间。它将为您提供已经排序的集合的最佳案例时间,最糟糕的情况是您不太可能遇到的病态排序。对于不可索引的集合(如链接列表 - betcha'不知道你可以使用Quicksort链接列表),你几乎不得不使用第一个项目,因此在使用它时要小心。

  • 如果第一次循环,a [0]小于数据透视,i等于j,那么你将A [0]与自身交换。

答案 1 :(得分:0)

您应该实施IComparer

  

此界面与Array.Sort和。{   Array.BinarySearch方法。它提供了一种自定义排序的方法   集合的顺序。有关参数的说明,请参阅比较方法   和返回值。此接口的默认实现是   比较班级。有关此接口的通用版本,请参阅   System.Collections.Generic.IComparer<T>

public class Reverse : IComparer
{
    int IComparer.Compare(Object x, Object y) => 
         ((new CaseInsensitiveComparer()).Compare( y, x ));  
}

上面的方法就是一个例子,然后你会:

IComparer reverse = new Reverse();
collection.Sort(reverse);

只需将您的比较传递给集合上的Sort,它就会执行并反转显示。您可以通过更好的控制进行更深入的控制,并根据特定的模型属性等进行实际排序。

我会调查Sort和上面的IComparer。有关IComparer here的详细信息。