我在尝试让这个快速排序算法100%工作时遇到了一些麻烦。截至目前,当它试图交换2个相同的数字时,它会挂起一点(试图解决你在代码中看到的那个)。
这件事几乎就在那里。我只是不确定我错过了什么。我花了几个小时试图找出它无济于事。
我正在上课,不幸的是我的老师说他无法帮助我,因为我正在做泛型(额外的功劳)而他只能在C#中使用字符串或整数(他主要是java / c ++)老师....他很久没有和c#一起工作了。)
Quicksort静态类
class QuickSort<T> where T : IComparable<T>
{
//No variables or properties, more of a helper class
//This is the method that will be called by the user.
//It ties the internal methods into one to sort the
//array. It needs an array passed into it, As well as
//the size of the array.
public static void QSort(T[] array,int size)
{
//If array is empty, or has 1 element, it is sorted.
//Return immediatly.
if (size == 1 || size == 0)
{ return; }
else
{
//Time to sort, pass in the array, the left bounds of 0,
//and the right bounds of high - 1 (the last element).
Partition(array, 0, size);
}
}
//This method splits the work area in half, putting lower
//values left of the pivot, and greater values right of
//the pivot.
private static void Partition(T[] array, int lower, int upper)
{
//If upper is less 1, then there is no
//sorting that can be done.
if ((upper - lower) < 2)
{ return; }
//Get the right bound -1, to make sure it stays
//within actual array bounds
int left = lower;
int right = upper-1;
//Set pivot to equal the middle most array. I used this
//expression because wikipedia mentions it will stop
//overflow and invalid pivot position that can come
//with exceptionally large arrays using the basic
//(a+b)/2 equation.
int pivot_index = left + (right - left) / 2;
T pivot = array[pivot_index];
while (left < right)
{
//array[left] < pivot
while ((array[left].CompareTo(pivot) <= 0) && (left < right))
{
left++;
}
//array[right] > pivot
while ((array[right].CompareTo(pivot) >= 0)&& (left < right))
{
right--;
}
if (left != right)
{
Swap(array, left, right);
left++;
right--;
}
}
//Send in the lower bound, and the pivot point.
Partition(array, lower, right);
//Send in the pivot point as lower bound, and upper
Partition(array, right+1, upper);
}
//This method simply swaps the first position with the second.
private static void Swap(T[] array, int position1, int position2)
{
T tempHolder = array[position1];
array[position1] = array[position2];
array[position2] = tempHolder;
}
}
主要课程
class Tester
{
static void Main(string[] args)
{
ContiguousList<int> tester = new ContiguousList<int>(100);
Random rand = new Random(5433);
for (int ii = 0; ii < tester.Size; ii++)
{
tester.SetElement(ii, rand.Next(0, 100));
}
for (int ii = 0; ii < tester.Size; ii++)
{
Console.WriteLine(tester.GetElement(ii).ToString());
}
Console.WriteLine();
tester.Sort();
for (int ii = 0; ii < tester.Size; ii++)
{
Console.WriteLine(tester.GetElement(ii).ToString());
}
}
}
这对我来说相当困难,因为我可以遵循的唯一在线实现是c ++(找到一个好的伪代码解释,如果我可以使用指针&gt;。&lt;)或者它们仅用于排序整数。 / p>
我想也许缺少交换,或者我的逻辑处理if array [left] == array [right]是否有问题。
(哦,不要介意主要的连续列表...我们的老师让我们编写自己的智能阵列并告诉我们使用它,这样我们就可以看到智能数组是如何工作的。)
感谢任何帮助人员。我的大脑真的很难过这个。
- 编辑 我更改了循环,因此一个检查&gt; = 0,另一个&lt; 0去除不需要的支票。
- 编辑 我再次调整了一下,现在它似乎几乎排序了,但不完全,我的前10个元素是1,1,2,3,2,3,6,5,4,5所以某种程度上有些东西没有得到当值相同时,交换正确。
Edit-- 只需重新阅读我正在使用的快速排序解释/伪代码,并注意到一点“这个版本只适用于具有独特元素的数组”警告......所以我是对的,因为当2个元素保持时,它必须做同样的价值,有些东西不起作用......虽然&gt;仍然难以解决它的问题。&lt;
答案 0 :(得分:2)
由于第一个循环,左侧元素不能小于枢轴。由于第二个循环,正确的元素不能超过枢轴。因此,如果它们相等,那么它们必须都与枢轴相等,因此它们最终的阵列中的哪一半并不重要。
无论如何,我认为修改代码所需要做的就是稍微调整这些行:
if (array[left].CompareTo(array[right]) == 0)
{
left++;
right--;
}
else if (left != right)
{
Swap(array, left, right);
left++;
right--;
}
但有一些简化:
left == right
隐含array[left].CompareTo(array[right]) == 0)
,因此您的left != right
测试是多余的。因此生成的代码如下所示:
if (array[left].CompareTo(array[right]) != 0)
{
Swap(array, left, right);
}
left++;
right--;
答案 1 :(得分:-1)
您应该更改交换方法以交换实际数据,而不是访问数组。在C#中你需要'ref'所以任何数据都作为参考发送:
private static void Swap(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}