我的快速排序实施有问题

时间:2011-08-25 01:18:21

标签: c algorithm sorting quicksort

新手程序员在这里尝试实施快速排序,但它不起作用。我查看了在线资源,但我似乎无法在我的实现中发现错误。提前谢谢。

编辑问题我似乎已经陷入快速排序功能,程序就会挂起。当我尝试使用printf进行调试时,原始数组似乎已使用意外数字(而不是原始列表)进行了修改,例如0。

void quicksort(int a[], const int start, const int end)
{
   if( (end - start + 1 ) < 2)
      return;

   int pivot = a[rand()%(end - start)];

   //Two pointers
   int L = start;
   int R = end;

   while(L < R)
   {
      while(a[L] < pivot)
         L++;
      while(a[R] > pivot)
         R--;
      if(L < R)
         swap(a,L,R);      
   }
   quicksort(a, start, L-1);
   quicksort(a, L+1, end );
}

void swap(int a[], const int pos1, const int pos2)
{
   a[pos1] ^= a[pos2];
   a[pos2] ^= a[pos1];
   a[pos1] ^= a[pos2];
}

int main()
{
   int array[20] = {0};
   int size = sizeof(array)/sizeof(array[0]);//index range = size - 1

   int i = 0;
   printf("Original: ");
   for (i; i < size; i++)
   {
      array[i] = rand()%100+ 1;
      printf("%d ", array[i]);
   }
   printf("\n");

   quicksort(array,0,size-1);

   int j = 0;
   printf("Sorted: ");
   for(j; j < size; j++)
      printf("%d ", array[j]);
   printf("\n");
}

附加问题:关于递归调用quicksort,左右指针是否总是指向每个分区末尾的枢轴?如果是这样,从开始调用快速排序到L-1和L + 1结束是否正确?

此外,交换前的if(L&lt; R)是否必要?

2 个答案:

答案 0 :(得分:2)

我认为问题源于逻辑中的两个错误。第一个是:

int pivot = a[rand()%(end - start)];

请注意,这总是选择[0,end - start]范围内的一个数据透视而不是[start,end]。我想你想要像

这样的东西
int pivot = a[rand()%(end - start) + start];

这样您就可以选择所需范围内的数据透视。

另一个错误出现在这个循环代码中:

while(L < R)
{
   while(a[L] < pivot)
      L++;
   while(a[R] > pivot)
      R--;
    if(L < R)
      swap(a,L,R);      
}

假设L < Ra[L]a[R]pivot都是相同的值。例如,如果您快速分配包含重复元素的范围,则可能会出现这种情况。当randrand的标准Linux实现一起使用时,它也出现了(我在我的机器上尝试了这个,27次重复了两次)。如果是这种情况,那么您永远不会移动L或R,因为循环中的条件总是评估为false。当需要重复时,您需要更新逻辑以分区元素,否则您将在此处进入无限循环。

希望这有帮助!

答案 1 :(得分:0)

在While语句之后,R应该小于L,试试这个:

quicksort(a, start, R);
quicksort(a, L, end ); 

并且声明if(L < R)不是必需的。