线性时间内从一个数组中找出第K个最小的元素——编程珠玑

线性时间内从一个数组中找出第K个最小的元素——编程珠玑

题目:编写程序,在O(n)时间内从数组x[0...n-1]中找出第k个最小的元素,算法中可以对x中的元素进行排序。
思路:快速排序选择一个pivot对数组进行划分,左边小于pivot,右边大于等于pivot,所以我们计算左边小于pivot(加上pivot)的个数count总共有多少,如果等于k,正是我们所要的,如果大于k,说明第k小的数在左边,那就在左边进行我们的递归;否则,在右边,那么说明右边的第k-count小的数就是我们所要的,在右边进行我们的递归。
算法实现一:
  1. #include<iostream>  
  2. using namespace std;  
  3.   
  4. inline void Swap(int a[],int i,int j)//内联函数,交换两个元素位置  
  5. {  
  6.     int temp=a[i];  
  7.     a[i]=a[j];  
  8.     a[j]=temp;  
  9. }  
  10.   
  11. int Partition(int a[],int p,int r)//根据pivot a[r]来划分数组  
  12. {  
  13.     int pivot=a[r];  
  14.     int low=p-1;  
  15.     int i;  
  16.     for(i=p;i<r;i++)  
  17.     {  
  18.         if(a[i]<=pivot)  
  19.             Swap(a,++low,i);  
  20.     }  
  21.     Swap(a,++low,r);  
  22.     return low;  
  23. }  
  24.   
  25. int RondomPartition(int a[],int p,int r)  
  26. {  
  27.     int i=p+rand()%(r-p+1);//随机选择一个pivot来划分  
  28.     Swap(a,i,r);  
  29.     return Partition(a,p,r);//返回轴位置  
  30. }  
  31.   
  32. int SelectKMin(int a[],int p,int r,int k)  
  33. {  
  34.     if(p==r)  
  35.         return a[p];  
  36.     int q=RondomPartition(a,p,r);  
  37.     int count=q-p+1;//计算 a[p..q]的元素数量   
  38.     if(k==count)//刚好,返回  
  39.         return a[q];  
  40.     else if(k<count)//在前半部分  
  41.         return SelectKMin(a,p,q-1,k);  
  42.     else //在后半部分  
  43.         return SelectKMin(a,q+1,r,k-count);  
  44. }  
  45.   
  46. int main()  
  47. {  
  48.     int a[]={2,3,4,1,5,10,9,7,8,6};  
  49.     int k=3;  
  50.     cout<<SelectKMin(a,0,9,k)<<endl;  
  51.       
  52.     return 0;  
  53. }  

算法实现二:
  1. #include"stdio.h"  
  2. int GetMinK(int A[],int n,int k)  
  3. {  
  4.     int s=-1,i=0,j=n-1,temp;  
  5.     int beg=i;  
  6.     int end=j;  
  7.     while(s!=k)  
  8.     {  
  9.         beg=i;  
  10.         end=j;  
  11.         temp=A[i];  
  12.         while(i<j)  
  13.         {  
  14.             while(i<j&&A[j]>=temp)j--;A[i]=A[j];  
  15.                    while(i<j&&A[i]<=temp)i++;A[j]=A[i];  
  16.         }  
  17.          A[i]=temp;  
  18.         s=i;  
  19.    
  20.      
  21.         if(s==k)  
  22.             return A[k];  
  23.         if(s>k){i=beg;j--;} //在左侧寻找   
  24.         if(s<k){j=end;i++;} //在右侧寻找   
  25.     }  
  26. }  
  27. int main()  
  28. {  
  29.     int A[]={2,3,4,1,5,10,9,7,8,6};  
  30.     int k=3;  
  31.     printf("第%d小元素为:(从0开始)\n%d ",k,GetMinK(A,10,k));  
  32.     return 0;  
  33. }  

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