为什么我的快速排序停止为大于~35000的阵列工作? (C ++)

时间:2014-12-07 19:42:06

标签: c++ optimization quicksort partitioning

这是我糟糕的实施方式:

void partition(people * arr, int size){
  if(size <= 1)
    return;

  people pivot = arr[rand() % size];
  int low = 0;
  int high = size - 1;

  while(low < high){
    while(  (arr[low].lname < pivot.lname) || (  (arr[low].fname <  pivot.fname) && (arr[low].lname == pivot.lname)  ) ||
    (  (arr[low].fname ==  pivot.fname) && (arr[low].lname == pivot.lname) && (arr[low].dob < pivot.dob)  )   )
        low += 1;

    while(arr[high].lname > pivot.lname  || ((arr[high].fname > pivot.fname)&&(arr[high].lname == pivot.lname)) ||
    ( (arr[high].fname ==  pivot.fname)&& (arr[high].lname == pivot.lname) && (arr[high].dob > pivot.dob) )   )
        high -= 1;

    people temp = arr[low];
    arr[low] = arr[high];
    arr[high] = temp;
   }

   partition(arr, low);
   partition(&(arr[low+1]), size - low - 1);
}



void kwiksort(people * arr, int size)
{  srand((unsigned int)time(0));
   partition(arr,size);
}

程序就好像它处于一个无限循环中并且基本上冻结了。 此外,如果有人能指出一些优化快速排序的方法,那就太棒了。

4 个答案:

答案 0 :(得分:2)

我怀疑问题在于您为变量int使用size类型。

正常int变量,如果我没有弄错,最多只能取2 ^ 15-1或32767的值。如果值较大,它将循环到负数。使用if语句等时,这可能会导致问题。

不要使用size声明int size,而是尝试long sizelong long size。长整数和长整数可以采用比常规整数更大的值。

答案 1 :(得分:1)

问题不在于使用人数。

请参阅代码的这种自包含修改,其中我只添加了一个main函数和“people”结构的声明。即使只有2人的东西,算法永远不会结束。

正如@ dietmar-kühl指出的那样,正确的答案是你的算法没有取得任何进展,但它并没有被冻结。

检查内部while的条件,是否有任何值组合会使您的数据无法进入?看来是这样。在这种情况下,您将永远交换同一对highlow

#include <ctime>
#include <iostream>

struct people
{
    int lname, fname, dob;
};

void partition(people * arr, int size){
  if(size <= 1)
    return;

  people pivot = arr[rand() % size];
  int low = 0;
  int high = size - 1;

  while(low < high){
    while(  (arr[low].lname < pivot.lname) || (  (arr[low].fname <  pivot.fname) && (arr[low].lname == pivot.lname)  ) ||
    (  (arr[low].fname ==  pivot.fname) && (arr[low].lname == pivot.lname) && (arr[low].dob < pivot.dob)  )   )
        low += 1;

    while(arr[high].lname > pivot.lname  || ((arr[high].fname > pivot.fname)&&(arr[high].lname == pivot.lname)) ||
    ( (arr[high].fname ==  pivot.fname)&& (arr[high].lname == pivot.lname) && (arr[high].dob > pivot.dob) )   )
        high -= 1;

    people temp = arr[low];
    arr[low] = arr[high];
    arr[high] = temp;
   }

   partition(arr, low);
   partition(&(arr[low+1]), size - low - 1);
}

void kwiksort(people * arr, int size)
{  srand((unsigned int)time(0));
   partition(arr,size);
}

int main()
{
    int the_size = 2;
    people* pa = new people[the_size]();
    kwiksort(pa, the_size);
}

答案 2 :(得分:0)

您似乎正在使用rand()初始化数组。可能,您的编译器的标准库使用这样的随机数生成算法,您可以在35026次调用后开始获取重复值。你的算法似乎停滞不前,即使你只用两个项目喂它,如果它们是相等的。

答案 3 :(得分:0)

您的版本存在一些问题:
1)如果两个值都等于pivot(一个应该),则两个循环都不会触发 2)交换后你不会高低移动(你可以放弃重新测试)

如果您只修复其中一个

,您的代码就会有效