随机快速排序

时间:2016-04-07 08:12:54

标签: c++ sorting quicksort

我为随机快速排序编写了以下代码。这会在分区函数中选择随机索引元素作为pivot_item。每当我运行代码时,p被设置为0或1,而不是所有从0到n-1的索引。你可以通过删除COMMENT 1验证这一点为什么会发生这种情况以及如何解决这个问题?

此外,正如您在输出中看到的那样,数组仅在索引1之后正确排序。为什么会这样,我该如何解决这个问题?

我的最后一个问题是无论我运行多少次程序,我都会在数组中获得相同的元素。 Isn< rand()应该每次都生成新的随机数吗?那么为什么每次都要对同一个数组进行排序呢?我该如何解决这个问题?

我的代码:

#include<iostream>
#include<cstdlib>
using namespace std;

int partition(int low,int high,int a[])
{
int p=sizeof(a)/sizeof(a[0]);
int index=rand()%p+0;
//COMMENT 1       cout<<endl<<index<<"----"<<endl;
int temp1=a[index];
a[index]=a[low];
a[low]=temp1;
int left,right,pivot_item=a[low];
left=low;
right=high;

while(left<right)
{
while(a[left]<=pivot_item)
left++;
while(a[right]>pivot_item)
right--;
if(left<right)
{
int temp=a[right];
a[right]=a[left];
a[left]=temp;
}
}
a[low]=a[right];
a[right]=pivot_item;
return right;
}

void quicksort(int low,int high,int a[])
{
int pivot;
if(low<high)
{
pivot=partition(low,high,a);
quicksort(low,pivot-1,a);
quicksort(pivot+1,high,a);
}
}

int main()
{
int n;
n=50;
int a[n];
int i;
for(i=0;i<n;i++)
a[i]=rand()%60;

quicksort(0,n-1,a);
cout<<endl;

for(i=0;i<n;i++)
cout<<a[i]<<endl;
return 0;
}

输出:

59
55
0
2
6
2
7
7
2
9
9
9
8
1
11
12
18
16
29
23
19
16
13
22
27
27
30
31
29
33
37
21
38
42
35
42
43
44
44
46
46
46
50
50
43
52
55
55
53
57

2 个答案:

答案 0 :(得分:1)

常见问题是,您没有获得要排序的实际数组的大小:

int partition(int low,int high,int a[]) // a is just a pointer!
{
    int p=sizeof(a)/sizeof(a[0]); // size of pointer/size of element

您需要传入数组的大小。这就是sizeof技巧糟糕的原因。相反,你可以使用:

template <typename T, std::size_t N>
size_t array_size(T (&)[N])
{ return N; }

然后应用array_size(a)将给出编译器错误,因为a不是数组。这个结构出现在许多库中(可能是boost,我会在检查后粘贴一个链接),并且会出现在C++17中的The Standard中。

还有better facilities for generating random numbers herehere for a good explanation why rand() is bad

答案 1 :(得分:1)

首先,主要是initialize the srand,例如与srand(time(NULL)),获得一个体面的随机。如果你不这样做,你会得到相同的&#34;随机&#34;每次运行程序的顺序。 (为此,您必须#include <time.h>。)

其次,正如评论中所指出的,你应该选择

的支点
index = low + (rand() % (high - low));

这是因为您选择枢轴的子阵列的大小为high-low+1,这通常与原始阵列的大小不同(这似乎是您尝试计算的使用sizeof魔法。

更新。正如Pete Becker所指出的那样,在开发的早期阶段(出于调试目的)不使用srand可能是个好主意。但是,如果您想要随机快速排序,请务必使用srand,这一点毫无疑问。