快排扩展——第k小的数
使用快排中的partition方法,可以很快找到一个无序序列中的第k小的数。
思想:对于一个数组a[0...n-1],分段成a[0...st-1],a[s],a[st+1...n-1]
分组后,a[0...st-1]里面的元素都小于等于a[st],a[st+1...n-1]里面的元素都大于等于a[st]. 所以,如果 st==k-1,那么a[st]就是要求的数。
如果 st>k-1,那么要求的数在a[0...st-1]里。   如果 st<k-1,那么要求的数在a[st+1...n-1]里。
因此我们把范围缩小到 a[0...st-1]或者a[st+1...n-1]里,然后对缩小范围后的数组也做同样的操作。
#include <iostream>
#include <algorithm>
#include <ctime>
#include <iterator>
using namespace std;
const int NUM = 20;
int partition(int a[],int left, int right)
{
 int L = left;
 int R = right;
 while(left < right)
 {
  while(a[left] <= a[L] && left != R)
   left++;
  while(a[right] >= a[L] && right != L)
   right--;
  swap(a[left],a[right]);
 }
 swap(a[left],a[right]);
 swap(a[L],a[right]);
 return right;
}
int Search(int a[], int left, int right, int k)
{
 int position = 0;
 int local_left = left;
 int local_right = right;
 while(local_left <= local_right)//注意:这里需要有等号
 {
  position = partition(a, local_left, local_right);
  if(position == k - 1)
   return a[position];
  else if( position < k - 1)
  {
   local_left = position + 1;
  }
  else
   local_right = position - 1;
 }
 //cout << "position : "<<position<<endl;
 //cout << "local_left: " << local_left << "\t" << "local_right: "<<local_right<<endl;
 return -1;
}
void QuickSort(int a[],int left,int right)
{
    int i;
    if(left<right)
    {
        i=partition(a,left,right);   //分割
        QuickSort(a,left,i-1);     //将两部分分别排序
        QuickSort(a,i+1,right);
    }
}
int main()
{
 int a[NUM] = {0};
 int k = 0;
srand(time(NULL));
 for(int i = 0; i < NUM; i++)
  a[i] = rand() % 100;
k = rand() % NUM;
//copy(a,a + NUM, ostream_iterator<int>(cout, " "));
cout<<endl;
 cout <<k<<"th number is : "<<Search(a,0,NUM - 1, k) <<endl;
 QuickSort(a,0,NUM - 1);
 ///下面主要是方便查看结果
 copy(a,a + NUM / 2, ostream_iterator<int>(cout, " "));
 cout << endl;
    copy(a + NUM / 2,a + NUM , ostream_iterator<int>(cout, " "));
 return 0;
}
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号