求数组第K大的数

问题:有一个大小为n的数组A[0,1,2,…,n-1],求其中第k大的数。
我们先分析原问题:有一个大小为 n的数组A[0,1,2,…,n-1],求其中第k大的数。

我们先取特例,令k=1,那么就是取最大的数,只要扫描一遍数组就可以确定该值,如果k=2,则扫描两边数组就可以确定第二大的数,依此类推下去,时间复杂度是O(k*n),如果k跟n是一个数量级,那么时间复杂度就是O(n*n)了,显然不是最优的解法。

考虑分治法,难点在于如何将该问题分解为两个子问题。

快速排序最基础的一步:

   随机取某一个数x,将其与数组末尾元素交换,然后将比其小的数交换至前,比其大的数交换至后。

这一步使某一数组的快速排序问题分解成两个子数组的排序问题,现在我们就依此来解决取第k大的数这个问题。

设数组下表从0开始,至n-1结束。

1、 随机取某个数,将其与数组末尾元素交换。

a) idx=rand(0,n-1);生成[0,n-1]间的随机数。

b) Swap(array[idx], array[n-1]);

2、 用末尾元素x,将比x小的数交换至前,比x大的数交换至后,并返回此时x在数组中的位置mid。

3、 如果mid==n-k,那么返回该值,这就是第k大的数。

如果mid>n-k,那么第k大的数在左半数组,且在左半数组中是第k-(n-mid)大的数。

如果mid

#include "iostream"  
using namespace std;  

int random_partion(int *p, int n)  
{  
     int idx=rand()%n;  
     swap(p[idx], p[n-1]);  
     int i=-1;    //i表示最后一个小于p[n-1]的元素的位置  
     int j=0;     //j用来扫描数组  
     for(j=0; j<n; j++)  
     {  
            //将小于p[n-1]的数交换到前半部分  
            if(p[j]<p[n-1])  
            {  
                swap(p[++i], p[j]);  
            }  
     }  
     swap(p[++i], p[n-1]);  
     return i;   
}  

int getMaxK(int *p, int n, int k)  
{  
    int mid;  
     if(k<=0)  
            return -1;  
     if(n<k)  
            return -1;  
     mid=random_partion(p, n);   //对原数组进行一次划分  
     if(mid == n-k)      //如果mid==n-k,那么返回该值,这就是第k大的数  
         return p[mid];  
     else if(mid<n-k)  
         return getMaxK(p+mid+1, n-mid-1, k);  //如果mid<n-k,那么第k大的数在右半数组,而且仍然是第k大数  
     else  
         return getMaxK(p, mid, k-(n-mid));   //如果mid>n-k,那么第k大的数在左半数组,且在左半数组中是第k-(n-mid)大的数  
}  

int main(void)  
{  
    int num,a[] = {12012, 3, 945, 965, 66, 232, 65, 7, 8, 898, 56, 878, 170, 13, 5};  
    num=getMaxK(a, 15, 4);  
    printf("%d\n",num);  
    system("pause");  
    return 0;  
}  
During the past decade there has been an explosion in computation and information technology. With it has come vast amounts of data in a variety of fields such as medicine, biology, finance, and marketing. The challenge of understanding these data has led to the development of new tools in the field of statistics, and spawned new areas such as data mining, machine learning, and bioinformatics. Many of these tools have common underpinnings but are often expressed with different terminology. This book descibes the important ideas in these areas in a common conceptual framework. While the approach is statistical, the emphasis is on concepts rather than mathematics. Many examples are given, with a liberal use of color graphics. It should be a valuable resource for statisticians and anyone interested in data mining in science or industry. The book's coverage is broad, from supervised learing (prediction) to unsupervised learning. The many topics include neural networks, support vector machines, classification trees and boosting--the first comprehensive treatment of this topic in any book. Trevor Hastie, Robert Tibshirani, and Jerome Friedman are professors of statistics at Stanford University. They are prominent researchers in this area: Hastie and Tibshirani developed generalized additive models and wrote a popular book of that title. Hastie wrote much of the statistical modeling software in S-PLUS and invented principal curves and surfaces. Tibshirani proposed the Lasso and is co-author of the very successful <EM>An Introduction to the Bootstrap</EM>. Friedman is the co-inventor of many data-mining tools including CART, MARS, and projection pursuit.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值