快速排序优化算法 - 编程珠玑

快速排序的是个递归的排序,其核心在划分算法上。
自己随手写的一个快速排序,果然和优化的快速排序差了好远。文后悔分别给出我写的三个进化版的划分函数。

另外,优化排序的一个手段是,把快排和直接插入排序结合起来。因为直接插入排序在序列基本有序的情况下速度非常快!
至于利用快排把数据排序到什么程度再用直接插入排序,珠玑的习题做了实验。有一个折中的值。


下面贴下三个逐步优化的划分算法

// 原始版信手写的快排
int partition( int arr[], int low, int high )
{
 int left = low;
 int right = high;

 int curr = left;
 //int curr = rand()

 while ( left<right )
 {
  while( curr<right )
  {
   if ( arr[curr]>arr[right] )
   {
    swap( arr[curr], arr[right] );
    curr = right;
    break;
   }
   --right;
  }

  while( left<curr )
  {
   if ( arr[curr]<arr[left] )
   {
    swap( arr[curr], arr[left] );
    curr = left;
    break;
   }
   ++left;
  }
 }

 return  curr;
}

// 1:优化了当面对有序序列时,时间复杂度也为n*log(n) 通过随机选择分支实现
// 2:去掉了没有必要的对t值的来回交换,只需要最后的时候放到目标位置上就可以了。
int partition_v2( int arr[], int low, int high )
{
 int left = low;
 int right = high;

 int rand_pos = rand() % (high - low+1) + low;
 swap( arr[low],arr[rand_pos] );

 int t = arr[low];
 int curr = low;

 while ( left<right )
 {
  while( curr<right )
  {
   if ( t>arr[right] )
   {
    arr[curr] = arr[right];
    curr = right;
    break;
   }
   --right;
  }

  while( left<curr )
  {
   if ( t<arr[left] )
   {
    arr[curr] = arr[left];
    curr = left;
    break;
   }
   ++left;
  }
 }

 return  curr;
}

// 1:优化了curr变量。抓住了快排的本质!
// 2:其实三个参数可以优化为2个参数!
int partition_v3( int arr[], int low, int high )
{
 int left = low;
 int right = high;

 int rand_pos = rand() % (high - low+1) + low;
 swap( arr[low],arr[rand_pos] );

 int t = arr[low];

 while ( left<right )
 {
  while( t>arr[right] )
  {
   --right;
  }

  while( t<arr[left] )
  {
   ++left;
  }
 }
 swap( arr[low], arr[right] );

 return  right;
}

// 快排算法 high = len-1
void qsort_rec( int arr[], int low, int high )
{
 if ( low>=high )
  return;
 
 int p = partition( arr, low, high );
 int p = partition_v2( arr, low, high );
 int p = partition_v3( arr, low, high );
 qsort_rec( arr, low, p-1 );
 qsort_rec( arr, p+1, high );
}

你可能感兴趣的:(编程,算法,优化)