我正在学习c ++,并且我对编程还比较陌生。我编写了一个C ++程序,该程序使用最后一个元素作为枢轴来实现快速排序算法。每当我尝试执行它时,答案总是错误的,对于某些特定的输入序列,我会遇到分段错误错误。
我尝试使用while循环并将其更改为“ if”语句,以查看是否发生任何事情。结果有所变化,但不正确。
//示例程序
#include <iostream>
using namespace std;
int partition(int a[],int l,int r)
{
//int l=0,r=p-1;
int p=r+1;
while(r>l)
{
while (a[l]<a[p])
{
l=l+1;
}
while(a[r]>a[p])
{
r=r-1;
}
//if(a[l]>a[r]){
int f=a[r];
a[r]=a[l];
a[l]=f;
//}
}
int k=a[l];
a[l]=a[p];
a[p]=a[l];
p=l;
return p;
}
void quicksort(int a[],int l,int r)
{
int p;
if (l<r){
p=partition(a,l,r);
quicksort(a,0,p-2);
quicksort(a,p+1,r);
}
}
int main(){
int k;
cout<<"enter the number of elements in array";
cin>>k;
int a[k];
for (int i=0;i<k;i++)
{
cin>>a[i];
}
//int p=k-1;
int l=0;
int r=k-2;
quicksort(a,l,r);
for (int i=0;i<k;i++)
{
cout<<a[i];
}
return 0;
}
实际结果: 输入数组中的元素数 4
3 0 1个 2
排序结果 1322
预期结果: 0123
答案 0 :(得分:0)
如果发布的代码为compiled,并且启用了警告,则会产生以下诊断:
prog.cc:25:9: warning: unused variable 'k' [-Wunused-variable] int k=a[l]; ^ prog.cc:47:10: warning: variable length arrays are a C99 feature [-Wvla-extension] int a[k]; ^
第一个是由函数partition
中的错字产生的:
int k=a[l];
a[l]=a[p];
a[p]=a[l]; // <-- That should be 'a[p] = k;' to swap the values
当然,交换这两个值的正确方法应该是
std::swap(a[l], a[p]);
通过使用适当的数据结构(在C ++中为std::vector
并将对它的引用而不是int *
)传递给其他函数,可以轻松解决第二个警告。
这些不是OP代码中唯一的问题,它似乎使用Lomuto分区方案实现了Quicksort算法的变体。
在OP的代码中,第一个调用类似于
quicksort(a, 0, k - 2); // k beeing the size of the VLA, it skips the last element
在使用vector
并遵循以范围的第一个元素和末尾的一个元素表示范围的惯例时,我们可以将入口点写为
// Note that std::vector::size() returns an unsigned type
quicksort(a, 0, a.size());
这样quicksort
函数可以实现为
void quicksort(std::vector<int> &a, size_t low, size_t high)
{
if ( low < high) {
size_t p = partition(a, low, high);
quicksort(a, low, p); // <- Note that OP's code uses '0' instead of 'low'
quicksort(a, p + 1, high);
}
}
如果我正确地猜到了OP试图实现的变体,则分区功能可以简化(并固定为)
size_t partition(std::vector<int> &a, size_t low, size_t high)
{
size_t p = high - 1; // <- Assumes high > 0
size_t i = low;
for( size_t j = low; j < p; ++j )
{
if(a[j] < a[p]) {
std::swap(a[i], a[j]);
++i;
}
}
std::swap(a[i], a[p]);
return i;
}