1. 程式人生 > >選擇問題(選擇數組中第K小的數)

選擇問題(選擇數組中第K小的數)

++i bsp 裝逼 mes tof quick 復雜度 names 返回

由排序問題可以引申出選擇問題,選擇問題就是選擇並返回數組中第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小的數)