首页 > 代码库 > 选择问题(选择数组中第K小的数)

选择问题(选择数组中第K小的数)

    由排序问题可以引申出选择问题,选择问题就是选择并返回数组中第k小的数,如果把数组全部排好序,在返回第k小的数,也能正确返回,但是这无疑做了很多无用功,由上篇博客中提到的快速排序,稍稍修改下就可以以较小的时间复杂度返回正确结果。

 

   代码如下:

 

  

#include<iostream>  
using namespace std;


#define Cutoff 3
 
int A[13] = {81,94,11,96,12,35,17,95,28,58,41,75,15};

void Swap(int &a, int &b)
{
   int c;
  c = a;
  a = b;
  b = c;
}

void InsetionSort (int A[], int N)   //插入排序
{
    int j, p;
    int Tmp;
    for (p = 1; p < N; p++)
    {
       Tmp = A[p];
       for(j = p; j > 0 && A[j - 1] > Tmp; j--)
           A[j] = A[j - 1];
       A[j] = Tmp;
    }
}


int Median (int A[],int Left, int Right)   //实现三数中值分割,选取枢纽元
{
   int Center = (Left + Right ) / 2;
 
   if(A[Left] > A[Center])
       Swap(A[Left] , A[Center]);
   if(A[Left] > A[Right])
       Swap(A[Left] , A[Right]);
   if(A[Center] > A[Right])
       Swap(A[Center] , A[Right]);
 
   /* A[Left] <= A[Center] <= A[Right] */
   Swap(A[Center], A[Right - 1]);    //把枢纽元放在倒数第二个
   return A[Right - 1];
}




void Qselete (int A[], int k, int Left, int Right)
{
   int i, j;
   int Pivot;
   if(Left + Cutoff <= Right)
   {
      Pivot = Median(A,Left,Right);
      i = Left; j = Right - 1;
      for( ; ; )
      {
          while(A[++i] < Pivot) { }
          while(A[--j] > Pivot) { }
          if(i < j)
              Swap(A[i], A[j]);
          else
              break;
      }
      Swap(A[i], A[Right - 1]);   // 恢复枢纽元的位置
     if(k <= i)
		Qselete (A, k, Left, i -1);
	 else
        Qselete (A, k, i + 1, Right);
   }
   else
   InsetionSort (A + Left, Right - Left + 1);
}

int  Quick_Sort (int A[], int k, int N)
{ 
	Qselete (A, k - 1, 0, N - 1);
	return A[k - 1];
}



int main ()
{
	 cout << Quick_Sort (A , 3, 13) << endl;
   return 0;
}

  思想很不错,值得学习。

 

    夜深了,,,

 

   唉,失恋的人就是矫情,写个博客还得装逼一下

选择问题(选择数组中第K小的数)