您的位置:首页 > 编程语言

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

2012-08-28 16:27 369 查看
线性时间内从一个数组中找出第K个最小的元素——编程珠玑

题目:编写程序,在O(n)时间内从数组x[0...n-1]中找出第k个最小的元素,算法中可以对x中的元素进行排序。

思路:快速排序选择一个pivot对数组进行划分,左边小于pivot,右边大于等于pivot,所以我们计算左边小于pivot(加上pivot)的个数count总共有多少,如果等于k,正是我们所要的,如果大于k,说明第k小的数在左边,那就在左边进行我们的递归;否则,在右边,那么说明右边的第k-count小的数就是我们所要的,在右边进行我们的递归。

算法实现一:

#include<iostream>  

using namespace std;  

  

inline void Swap(int a[],int i,int j)//内联函数,交换两个元素位置  

{  

    int temp=a[i];  

    a[i]=a[j];  

    a[j]=temp;  

}  

  

int Partition(int a[],int p,int r)//根据pivot a[r]来划分数组  

{  

    int pivot=a[r];  

    int low=p-1;  

    int i;  

    for(i=p;i<r;i++)  

    {  

        if(a[i]<=pivot)  

            Swap(a,++low,i);  

    }  

    Swap(a,++low,r);  

    return low;  

}  

  

int RondomPartition(int a[],int p,int r)  

{  

    int i=p+rand()%(r-p+1);//随机选择一个pivot来划分  

    Swap(a,i,r);  

    return Partition(a,p,r);//返回轴位置  

}  

  

int SelectKMin(int a[],int p,int r,int k)  

{  

    if(p==r)  

        return a[p];  

    int q=RondomPartition(a,p,r);  

    int count=q-p+1;//计算 a[p..q]的元素数量   

    if(k==count)//刚好,返回  

        return a[q];  

    else if(k<count)//在前半部分  

        return SelectKMin(a,p,q-1,k);  

    else //在后半部分  

        return SelectKMin(a,q+1,r,k-count);  

}  

  

int main()  

{  

    int a[]={2,3,4,1,5,10,9,7,8,6};  

    int k=3;  

    cout<<SelectKMin(a,0,9,k)<<endl;  

      

    return 0;  

}  

算法实现二:

#include"stdio.h"  

int GetMinK(int A[],int n,int k)  

{  

    int s=-1,i=0,j=n-1,temp;  

    int beg=i;  

    int end=j;  

    while(s!=k)  

    {  

        beg=i;  

        end=j;  

        temp=A[i];  

        while(i<j)  

        {  

            while(i<j&&A[j]>=temp)j--;A[i]=A[j];  

                   while(i<j&&A[i]<=temp)i++;A[j]=A[i];  

        }  

         A[i]=temp;  

        s=i;  

   

     

        if(s==k)  

            return A[k];  

        if(s>k){i=beg;j--;} //在左侧寻找   

        if(s<k){j=end;i++;} //在右侧寻找   

    }  

}  

int main()  

{  

    int A[]={2,3,4,1,5,10,9,7,8,6};  

    int k=3;  

    printf("第%d小元素为:(从0开始)\n%d ",k,GetMinK(A,10,k));  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐