您的位置:首页 > 其它

算法导论思考题9-3小顺序统计量问题

2015-04-14 22:10 190 查看
一、题目

要在n个数中选出第i个顺序统计量,SELECT在最坏情况下需要的比较次数T(n)满足T(n)=θ(n)。但是,隐含在θ记号中的常数项是非常大的。当i相对n来说很小时,我们可以实现一个不同的算法,它以SELECT作为子程序,但在最坏情况下,所做的比较次数更少。

a.设计一个能用Ui(n)次比较在n个元素中找出第i小元素的算法,其中,



(提示:从⌊n/2⌋个不相交的对的两两比较开始,然后对由每对中的较小元素构成的集合进行递归。)

二、解题思路



假设输入数组为A[p],A[p+1],...,A[p+n-1],共n个数

1、首先,取m=⌊n/2⌋,将输入数组进行划分,第一组第1...m个数,第二组为第m+1...2m个数,如果n为奇数,还会多一个数未分组A[2m+1].

2、分别对两部分的第j个数进行比较(0≤j≤m),就是A[p]和A[p+m],A[p+1]和A[p+m+1],...,如果A[p+j]<A[p+m+j],则交换它们,即把较小元素放到A[p+m+j],较大元素放到A[p+j]。

3、对A[p+m]...A[p+n-1]递归执行1、2,这里要注意,如果递归中对两个分组的元素进行调换,那么他们上一层分组左侧组相应位置也得调换,依次类推,上上层以及更多层的相应位置都得调换,保证每个分组左侧一组依次大于右侧一组。

拿上图来说,将12个元素划分为蓝色与红色两部分,分别比较Aj和Bj(j=1...6),小的放到Bj里,然后再对红色部分划分为两部分,如果B4>B1,交换B4与B1,同时交换A4与A1,交换后元素大小如箭头所示。再对红色右半部分划分,如果B4<B5,须交换B4、B5,同时交换B1与B2、A1与A2、A4与A5.

4、每递归一次,分组就减少一半,当i大于等于分组元素个数的一半时,停止递归,采用SELECT方法对最后分组L划分,此时L前i个数是该分组最小的i个数,倒数第二个分组L1元素依次大于L,那么L和L1的第i小数就在L的前i个数和L1的前i个数之中,利用SELECT对这2i个数操作(如果n为奇数,就将最后一个数也加进去),找到这两分组前i小的数,返回上一层调用当中。

5、在上一层调用中,用SELECT对左右分组前i个数共2i个数操作,然后再返回,直到顶层。

三、伪代码如下:(SELECT()为9.3节最坏情况线性时间选择算法,与书中稍有不同,这里需要同时交换各层次分组相同位置的元素)

S_SELECT(A,p,r,i,g)

n = r-p+1;

if i>=n/2

SELECT(A,p,r,i,g)//▲

else

m = ⌊n/2⌋

g[]=m;//数组g保存各次分组的大小

for j=0 to m-1

if A[p+j] < A[p+m+j]

exchange(A[p+j],A[p+m+j])//▲

S_SELECT(A,p+m,r,g)

B=array()

for j=1 to i

B[j] = A[p+j-1]

B[j+i]=A[p+m+j-1]

if n is odd//如果n是奇数,那么最后会多出来一项

B[2i+1] = A[p-1+n]

B = SELECT(B,1,2i+1,i)

else B = SELECT(B,1,2i,i)//此时B[1]...B[i]是B前i小的数

A[p]...A[p+i-1] = B[1]...B[i]//▲

return A[p+i-1]

加黑色三角处需要同时交换各层次分组相同位置的元素,写起来比较复杂,代码中没有体现出来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: