我正在尝试从头开始实施和构建快速排序算法,我一直在浏览不同的帖子,这似乎是一个热门话题,我不完全确定如何解释其他人用它做了什么让我的工作。
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>
答案 0 :(得分:1)
第一步 - 实际了解Quicksort中发生的事情......
基本Quicksort算法
现在,这个特殊的实现有点奇怪。它试图在适当的位置进行,这没关系,但它似乎没有移动枢轴,这意味着它将被覆盖(因此在分区的中间发生变化)
一些挑剔的东西。
不要在循环中间创建新的Random
对象。在循环外创建一次,并重用它。这有几个原因。 1)它需要一个(相对)长的时间,2)它以千分之一的时间播种,所以两个在彼此毫秒内创建的两个将创建相同的序列 - 在这里你总是得到相同的轴。
实际上,最好不要使用随机数据。这可能是由对算法的基本误解所启发的。最初,有人建议,因为选择哪个项目作为枢轴无关紧要,你不妨选择第一个项目,因为它最简单。但后来人们发现,已经排序过的集合的最坏情况是以枢轴为中心。所以,他们自然而然地走了另一条路,决定随意转向。那是愚蠢的。对于任何给定的集合,存在导致最坏情况时间的枢轴。通过使用随机枢轴,您可以增加偶然击中它的机会。最佳选择:对于可索引的集合(如数组),最好将物品放在集合的中间。它将为您提供已经排序的集合的最佳案例时间,最糟糕的情况是您不太可能遇到的病态排序。对于不可索引的集合(如链接列表 - betcha'不知道你可以使用Quicksort链接列表),你几乎不得不使用第一个项目,因此在使用它时要小心。
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的详细信息。