【问题标题】:Problem with my quicksort implementation我的快速排序实现有问题
【发布时间】:2011-11-03 06:56:04
【问题描述】:

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

EDIT 我遇到的问题似乎卡在快速排序功能中,程序就挂起。当我尝试使用 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");
}

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

另外,交换之前的 if (L

【问题讨论】:

  • 什么症状?当前结果与预期?请不要只要求我们修复您的大块代码。
  • 糟糕。它卡在某个地方;它不会退出快速排序。当它以某种方式成功退出时,它引入了原始列表中没有的数字。
  • 进行真正的交换,不要那样做 xor mumbo jumbo。
  • 请注意,如果您尝试将对象与自身交换,则 xor 技巧会失败(在这种情况下不是问题)。

标签: c algorithm sorting quicksort


【解决方案1】:

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

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 &lt; R,但a[L]a[R]pivot 都是相同的值。例如,如果您正在对包含重复元素的范围进行快速排序,则可能会出现这种情况。当您将randrand 的标准Linux 实现一起使用时也会出现这种情况(我在我的机器上试过这个,27 被复制了两次)。如果是这种情况,那么您永远不会移动 L 或 R,因为循环中的条件总是评估为假。当可能出现重复时,您需要更新对元素进行分区的逻辑,否则您将在此处进入无限循环。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

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

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

    并且声明if(L &lt; R) 是不必要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-02
      • 2023-01-31
      • 2018-09-20
      • 1970-01-01
      • 2019-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多