我尝试实现Quicksort算法。这是Quicksort本身的代码
void quicksortlast(double* a, int first, int last)
{
if(first<last)
{
int pIndex=partition(a, first, last);
quicksortlast(a, first, pIndex-1);
quicksortlast(a, pIndex+1, last);
}
}
pIndex变量是元素在正确位置的位置。我选择最后一个数组元素作为分区方案中的枢轴。以下代码应该对数组进行分区:
int partition(double* a, int first, int last)
{
int pivot=last;
int i=0;
int j=last-1;
while(i<j && i<=last && j>=0)
{
while(a[i++]<a[pivot])
{
if(i>last)
break;
}
while(a[j--]>a[pivot])
{
if(j<0)
break;
}
if(i<j && i<=last && j>=0)
{
swap(a,i,j);
i++;
j--;
}
}
swap(a,j,pivot);
return j;
}
分区功能使用定义为
的交换功能void swap(double* a, int left, int right)
{
int temp=a[left];
a[left]=a[right];
a[right]=temp;
return;
}
当然,还有test.cpp函数可以测试算法。
#include <iostream>
#include "qsort.h"
using namespace std;
int main()
{
int len;
cin>>len;
double* a= new double[len];
for(int i=0;i<len;i++)
cin>>a[i];
cout<<"Unsorted array"<<endl;
print(a,len);
quicksortlast(a, 0, len-1);
cout<<"printed array"<<endl;
print(a, len);
return 0;
}
第一次调用print函数会打印未排序的数组,但是它给我一个错误消息:
Segmentation fault(core is dumped).
我知道可以访问某些内存位置,但是我不知道实际错误在哪里。我们非常感谢您的帮助。
答案 0 :(得分:0)
您的代码进入无限循环,从而导致stack overflow error。该算法的伪代码可以在维基百科上找到,正确的实现应该是这样的:
#include <stdio.h>
// Example program
#include <iostream>
#include <string>
void swap(double* a, int left, int right)
{
int temp = a[left];
a[left] = a[right];
a[right] = temp;
return;
}
int partition(double* a, int first, int last)
{
int pivot = last;
int i = 0;
for (int j = 0; j < last - 1; j++) {
if (a[j] < pivot) {
swap(a, i, j);
i++;
}
}
swap(a, i, last);
return i;
}
void quicksortlast(double* a, int first, int last)
{
if (first < last)
{
int pIndex = partition(a, first, last);
quicksortlast(a, first, pIndex - 1);
quicksortlast(a, pIndex + 1, last);
}
}
using namespace std;
int main()
{
int len;
cin >> len;
double* a = new double[len];
for (int i = 0; i < len; i++)
cin >> a[i];
quicksortlast(a, 0, len - 1);
return 0;
}
答案 1 :(得分:0)
分区代码需要一些修复。如果应该首先使用代码,则代码使用0。 swap函数从double转换为int并返回,可以使用std :: swap代替。
对于从数组的两端向中间扫描的快速排序,通常将中间用作枢轴,因为这样就不必使用索引检查来避免扫描超出数组的两端,这可能是原因代码出现分段错误。当扫描索引相互交叉时,扫描将停止。返回哪个索引以及该索引代表什么取决于具体的实现。
典型的Hoare分区方案的示例代码。如果使用迭代器代替索引,则不能使用low-1,并且分区函数需要稍作更改,以使用a [i] <枢轴而不是a [++ i] <枢轴来处理初始比较。高+1不是问题,因为这与“结束”迭代器相同。
int Partition(double a[], int low, int high)
{
double pivot = a[low+(high-low)/2];
int i = low - 1;
int j = high + 1;
while(1)
{
while(a[++i] < pivot);
while(a[--j] > pivot);
if(i >= j)
return j;
std::swap(a[i], a[j]);
}
}
void QuickSort(double a[], int low, int high)
{
if (low < high)
{
int index = Partition(a, low, high);
QuickSort(a, low, index); // not index - 1 for Hoare
QuickSort(a, index + 1, high);
}
}
像Hoare这样的示例分区方案,它使用后递增和后递减
int partition(double a[], int first, int last)
{
double pivot = a[first+(last-first)/2]; // use middle for pivot
while(first <= last) {
while (a[first] < pivot)
first++;
while (a[last] > pivot)
last--;
if(first > last)
break;
std::swap(a[first],a[last]);
first++;
last--;
}
return first; // index to 1st element of right part
}
void quicksort(double a[], int first, int last)
{
if(first >= last) // style change
return;
int index=partition(a, first, last);
// index to 1st element of right part
quicksort(a, first, index-1);
quicksort(a, index, last); // not index+1 for this implementation
}