我通过选择第一个元素作为枢轴来实现快速排序。它适用于一般测试用例,但考虑到数组反向排序的情况,例如5 4 3 2 1.我理解它在哪里引发运行时错误。但我无法正确修复它。第一个元素的实现是否正确?请提出修改建议。
public static void quicksort(int low,int high)
{
if(low<high)
{
int temp=0;
int pivot=a[low];
int large_index=low+1;
int small_index=high;
while(large_index<=small_index)
{
while(a[small_index]>pivot)
small_index--;
while(a[large_index]<pivot)
large_index++;
if(large_index<=small_index)
{
temp = a[large_index];
a[large_index]= a[small_index];
a[small_index]= temp;
large_index++;
small_index--;
}
}
temp = a[small_index];
a[small_index]= a[low];
a[low]= temp;
quicksort(low,small_index-1);
quicksort(small_index+1,high);
}
}
答案 0 :(得分:2)
存在多个缺陷:
a)在循环外不必要的交换
temp = a [small_index]; a [small_index] = a [low]; a [low] = temp;
b)large_index的初始化不正确。
c)调用递归函数而不检查值 small_index和large_index。
我已经纠正了它们,
现在该功能将如下所示:
if (low < high) {
int temp = 0;
int pivot = a[low];
int large_index = low;
int small_index = high;
while (large_index <= small_index) {
while (a[small_index] > pivot)
small_index--;
while (a[large_index] < pivot)
large_index++;
if (large_index <= small_index) {
temp = a[large_index];
a[large_index] = a[small_index];
a[small_index] = temp;
large_index++;
small_index--;
}
}
if(low < small_index)
{
quicksort(low, small_index);
}
if(large_index < high)
{
quicksort(large_index, high);
}
}
现在,观察你的代码中的变量:(除非输入没有排序,否则你的代码将在任何给定输入的最后一次迭代中失败)
考虑输入2,1
1st iteration:
pivot = 2
large_index = 1;
small_index = 1;
while1:
1<=1 -> true
while2: 1>2 false.
while3: 1<2 true. -> large_index++
2nd time in while loop large_index =2 which is > the size of a.
导致IndexArrayOutOfBounds。
这表明您对 large_index的初始化错误。
应该是: large_index = low ;而不是低+ 1;
希望这有帮助。
答案 1 :(得分:0)
以上循环继续在high
上方,当large_index
已经从枢轴上方开始时,它发生的枢轴大于位于其后面的每个元素:
while(a[large_index]<pivot)
large_index++;
当然可能还有其他错误。
答案 2 :(得分:0)
经过一些尝试,我能够制作Quicksort功能,现在工作正常。 @BatScream我仍然在我的代码中使用了small_index = low + 1。所以这不是我猜的错误。原始的快速排序算法遵循这种机制。如需参考,请观看Princeton教授Robert Sedgewick关于QuickSort的讲座。请注意编辑的快速排序算法是否存在缺陷。
public static void quicksort(int low,int high)
{
if(low<high)
{
int temp=0;
int pivot=a[low];
int large_index=low+1;
int small_index=high;
while(large_index<small_index)
{
while(a[large_index]<pivot) {
if(large_index==high)
break;
large_index++;
}
while(a[small_index]>pivot)
{
if(small_index==low)
break;
small_index--;
}
if(large_index<small_index) {
temp = a[large_index];
a[large_index]= a[small_index];
a[small_index]= temp;
large_index++;
small_index--;
}
}
if(a[small_index]<pivot) {
temp = a[small_index];
a[small_index]= a[low];
a[low]= temp;
}
if(low<small_index) //Recursively sort the left half.
{
quicksort(low,small_index-1);
}
if(high>small_index) //Recursively sort the right half.
{
quicksort(small_index+1,high);
}
}
}