加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

线性时间查找序列第k小数的算法

(2011-03-27 16:16:45)
标签:

杂谈

分类: 算法篇

这学期学习算法分析与设计课程,今天看了看中位数,总结了总结算法,实现代码一会儿再贴

Description

从一组输入数据中找出第k小的数,要求在线性时间内作出选择。

Solution

传统的方法是对这组数据 进行排序(插入冒泡等),然后从排序后的序列中比较找出第k小的数,但是这种方法复杂度是O(nlogn)(采用快速排序)

为了在线性时间内得到结果,又如下方法,假设输入数组为a[]

方法一: 类似于二分排序

Select(int[] a, int start, int end, int k)

{

//利用快速排序方法,将数组以pivot值分成两部分,下标为j

j = Partition(a,start,end);

//利用pivot值的下标jk进行比较:

If( k = j)

    Return a[j]

If( k < j )

      //表示第k小的数在前半部分,则对前部分递归调用此方法

    Select(a,start,j-1,k);

If( k > j )

//表示第k小的数在后半部分,则对后部分递归调用此方法

Select(a,j+1,end,k-j);

}

分析:此种方法的平均时间复杂度是O(n);但是在最坏情况下,可能总是按剩下的元素中最大的进行划分,则复杂度为O(n*n),因此如果能在线性的时间内找到划分的基准,则可以在最坏情况下复杂度为O(n)时找到第k小的数。具体看下面的方法。

方法二: O(n)下找到划分基准。

1.       找基准

(a)    将数组a五个数为一组,分成[n/5]个组

(b)    [n/5]个组的数进行组内排序,采用冒泡就行

(c)    选择b中每组的中位数,将这些中位数交换到数组的最前面,此时a[0-(end-start)/5 -1]中存的就是这些中位数

(d)    c中的0-(end-start)/5 -1个中位数进行排序,取出排序后这些中位数的中位数x

X就是需要的基准。

2.       x为基准进行划分,剩下的方法同方法一,即划分,比较,递归寻找。

分析:此种方法的最坏情况下复杂度也是O(n)

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有