得到第K个大的数算法研究

本文为原创,如需转载,请注明作者和出处,谢谢!

    第一种算法是最容易想到的,就是利用快速排序的思想,将一个数组分成以某一个数X为轴,左边的所有的数都比X小,而右边的数都比X大。但我快速排序不同的是,在这个算法中只考虑X的一边,而不是两边都考虑。

   如果X的位置是i,那么要得到第k个数,如果k<=i, 那么这个数一定在i的左边,否则在i的右边。

源码如下:

#include <stdio.h>
#include 
<stdlib.h>
int new_random(int min, int max)
{
    
return (min + (int)(((float)rand()/RAND_MAX)*(max - min)));
}
void swap(int *a, int *b)
{
    
int c = *a;
    
*= *b;
    
*= c;
}

int partition(int A[], int p, int r)
{
    
int i = p - 1, j;
    
for(j = p; j < r; j++)
    {
        
if(A[j] <= A[r])
        {
            i
++;
            swap(
&A[i], &A[j]);
        }
    }
    swap(
&A[i + 1], &A[r]);
    
return i + 1;
}

int randomize_partition(int A[], int p, int r)
{
    
int i = new_random(p, r);
    swap(
&A[i], &A[r]);
    
return partition(A, p, r);
}

//第一种算法
int randomized_select(int data[], int p, int r, int k)
{
    
if(k > (r - p + 1)) return 0;
    
if(p == r) return data[p];
    
int i = randomize_partition(data, p, r);
    
//int i = partition(data, p, r); //不好使,死循环, 必须用随机数,在第二步时总是在最大数处划分

    
int count = i - p + 1;
    
if(k <= count)
        
return randomized_select(data, p, i, k);
    
else
        
return randomized_select(data, i + 1, r, k - count);
}


    另外一种对这种算法做了一下改进,即将数组每5个数一组进行排序,然后取得它的中位数,再对这些中位数进行排序。然后先出的轴X最比较好的,因此X的左边和右边的数总是很平均,所以平均查找速度更快。算法如下:

void quicksort(int data[], int b, int e)
{
    
if(b < e)
    {
        
int k = partition(data, b, e);
        quicksort(data, b, k 
- 1);
        quicksort(data, k 
+ 1, e);
    }
}

int partition1(int A[], int p, int r, int x)
{
    
int i = p - 1, j;
    
for(j = p; j <= r; j++)
    {
        
if(A[j] <= x)
        {
            i
++;
            swap(
&A[i], &A[j]);
        }
    }
    A[i 
+ 1= x;
    
return i + 1;
}
//第二种算法
int select_new(int data[], int p, int r, int k)
{
    
if(r - p < 75)
    {
        quicksort(data, p, r);
        
return data[p + k - 1];
    }   
    
int i;
    
for(i = 0; i <= (r - p - 4/ 5; i++)
    {
        quicksort(data, p 
+ 5 * i, p + 5 * i + 4);
        swap(
&data[p + 5 * i + 2], &data[p + i]);
    }
    
int x = select_new(data, p, p + (r - p - 4/ 5, (r - p - 4)/10); // 得到更好的轴X
    i = partition1(data, p, r, x);
    
int count = i - p + 1
    
if(k <= count)
        
return select_new(data, p, i, k);
    
else
        
return select_new(data, i + 1, r, k - count);
}

int main()
{
    
int data[] = {3173481167812-1100};
    printf(
"%d\n", randomized_select(data, 092));
    
int data1[] = {3173481167812-1100};
    printf(
"%d\n", select_new(data1, 092));
   
     
return 0;
}



国内最棒的Google Android技术社区(eoeandroid),欢迎访问!

《银河系列原创教程》发布

《Java Web开发速学宝典》出版,欢迎定购

posted on 2008-05-12 20:55 银河使者 阅读(1204) 评论(0)  编辑  收藏 所属分类: algorithmC/C++ 原创


专题:Android  iPad  jQuery  Chrome OS

博客园首页  IT新闻  知识库  学英语  Java程序员招聘
标题  
姓名  
主页
验证码 *  
内容(请不要发表任何与政治相关的内容)  
  登录      
每天10分钟,轻松学英语


网站导航:
 
<2008年5月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

导航

统计

公告

我的其他blog

http://nokiaguy.cnblogs.com
http://blog.csdn.net/nokiaguy

我的著作





正在读的书




常用链接

留言簿(31)

我参与的团队

随笔分类(662)

随笔档案(255)

文章分类(1)

文章档案(4)

相册

ADSL、3G查询

CSDN

eclipse

ibm

Java EE

Linux

Web

云服务

代理网站

关注的网站

喜欢的Blog

图书出版

开发工具

手机铃声

操作系统

数学

文件格式

源码资源

移动(Mobile)

编程语言

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜