[英]Need help with (an attempt of) a quicksort algorithm in c++
我尝试了多种不同的方式来编写此代码,但大多数情况下,我陷入了无休止的循环。 此版本的代码根本不对它进行排序,我也不知道问题出在哪里。
void quickSort(int unsorted[], int left, int right) {
int i = left, j = right;
int pivot = (left + right) / 2;
while (i == pivot || j == pivot) {
if (unsorted[i] >= unsorted[pivot] && unsorted[pivot] >= unsorted[j])
swap(unsorted[i], unsorted[j]);
if (i < pivot)
i++;
if (j > pivot)
j--;
};
if (left < j && unsorted[left] != unsorted[j])
right = pivot, quickSort(unsorted, left, right);
if (i < right && unsorted[right] != unsorted[i])
left = pivot +1, quickSort(unsorted, left, right);
}
unsorted
是一个数组,其中填充了0到200之间的100个随机值。
抱歉更新缓慢。 关于代码,我重写了大部分代码。 这是现在的样子:
void quickSort(int unsorted[], int left, int right)
{
int i = left,
j = right,
count = 0;
int pivot = (left + right) / 2;
do
{
while (unsorted[i] < unsorted[pivot])
i++;
while (unsorted[j] > unsorted[pivot])
j--;
if (unsorted[i] >= unsorted[j] && i <= j)
{
swap(unsorted[i], unsorted[j]);
i++;
j--;
count++;
}
if (i == pivot && unsorted[pivot] < unsorted[j] && count == 0)
{
swap(unsorted[i], unsorted[j]);
i++;
j--;
count++;
}
if (j == pivot && unsorted[pivot] < unsorted[i] && count == 0)
{
swap(unsorted[i], unsorted[j]);
i++;
j--;
count++;
}
if (i == j && unsorted[i] > unsorted[pivot] && count == 0)
{
swap(unsorted[i], unsorted[pivot]);
i++;
j--;
count++;
}
if (i == j && unsorted[i] < unsorted[pivot] && count == 0)
{
swap(unsorted[i], unsorted[pivot]);
i++;
j--;
}
count = 0;
} while (i < j);
if (left < j)
quickSort(unsorted, left, j);
if (i < right)
quickSort(unsorted, i, right);
}
我一直在尝试使用10个随机值一次又一次地尝试此代码,并且大多数时候都可以使用。 在某些情况下,它不起作用,我正在尝试找出时间。
一个不起作用的示例是以下值:160、151、159、112、7、121、105、48、186。
解决了。 删除了很多代码,使其变得更加简单,但至少可以正常工作。 甚至不知道您是否可以将其称为快速搜索,但这是最终版本:
void quickSort(int unsorted[], int left, int right)
{
int i = left,
j = right;
int pivot = right;
do
{
while (unsorted[i] < unsorted[pivot])
i++;
while (unsorted[j] > unsorted[pivot])
j--;
if (unsorted[i] >= unsorted[j] && i <= j)
{
swap(unsorted[i], unsorted[j]);
i++;
j--;
}
} while (i < j);
if (left < j)
quickSort(unsorted, left, j);
if (i < right)
quickSort(unsorted, i, right);
}
您没有在长度为1的数组上测试功能。
使它工作,然后尝试使用长度为2的数组。
一旦工作,给它一个长度为3的数组很有可能会工作。
编辑:
包含可复制示例的荣誉。
此代码在递归之前失败。 第一步是选择一个枢轴元素,然后移动一些元素,直到该枢轴元素不小于其左侧且不大于其右侧。 您的代码无法跟踪将哪个元素视为数据透视元素。 它替换掉了透视元素 ,但似乎认为同一位置仍然是透视。 到目前为止,尝试用铅笔和纸来工作该算法,您将明白我的意思。
这张支票对我来说似乎很奇怪
while (i == pivot || j == pivot)
至少不应该
while (i != pivot && j != pivot)
PS:我认为这不是唯一的问题,但是首先...
没有看到swap
,我的第一个直觉是您的swap
按值接受参数。 即它交换两个副本,而不是参数本身。
噢亲爱的。 对不起,乔,但是对于您的代码而言,情况看起来并不好。 它需要进行许多计算机血管手术,即使那样,我也不确定它能否成功。 让我们写一个处方,我让你动用手术刀:
现在我们需要分区。 让我们做一个我们可以想到的最简单的分区。 当您刚开始使用quicksort时,我建议您使用以下方法: [ < pivot | >= pivot | unsorted ]
[ < pivot | >= pivot | unsorted ]
[ < pivot | >= pivot | unsorted ]
。 这就是我们在每个步骤中想要的不变性。 一开始,所有内容都将位于未排序的分区中。 最后,未排序的分区中将没有任何内容。 我们应该怎么做?
left+1
到right
循环。 [ < pivot ]
分区中(我留给您-您需要跟踪左侧两个分区之间的边界)。 如果不是,我们继续。 [ < pivot | pivot | >= pivot ]
[ < pivot | pivot | >= pivot ]
[ < pivot | pivot | >= pivot ]
。 快速排序最左边和最右边的分区,实际上应该在查找此代码。 尝试像[ < pivot | unsorted | >= pivot ]
[ < pivot | unsorted | >= pivot ]
[ < pivot | unsorted | >= pivot ]
分区(如果正确完成,它将更快)。 我认为您当前的实现正在尝试进行这种分区,但是除非i或j指向等于枢轴的元素,否则不会进行任何交换。 这种划分比较棘手,我建议我们在任何比赛之前都给您一个代码脉冲。
希望这会使您的代码成形,但这只是一个非常基本的快速排序。 您应该研究Bentley-McIlroy分区,并选择合适的选择方法以使其更高级。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.