关于最坏情况线性时间选择算法的疑惑

allantop 2010-11-27 08:00:32
算法导论的9.3节讲了最坏情况线性时间选择,然后我在CSDN博客上看到有人发了这个问题的算法,连接如下:
http://blog.csdn.net/lewutian/archive/2009/09/13/4549650.aspx
他的代码我贴了过来,有些地方我看不懂,请大家指点一下
主要有以下几个疑问:
for(int i=0;i<(r-p-4)/5;i++)
这里为什么要减去4,为什么不把整个数组都分组找一次中位数,而是去掉最后几个元素 。
int x=select(p,p+(r-p-4)/5,(r-p+6)/10);
这里为什么要加上6,我觉得可能和前面减去4有关,但前面的也不懂,所以这里也不懂了。

#include<iostream.h>

#include<stdlib.h>

#include<time.h>

#define MAX_VALUE 10000

#define random() rand()%MAX_VALUE

#define N 10000

int a[N];

class Find

{

public:

void bubble(int first,int end) //冒泡排序

{

for(int flag=first;flag<end;flag++)

for(int i=end;i>flag;i--)

if(a[i]<a[i-1])

{ int t=a[i];

a[i]=a[i-1];

a[i-1]=t;

}

}

int partition(int p,int r,int x) //数组a中从a[p]到a[r]的元素按照x划分,大于x的在左边,小于x的在右边

{

int i,j;

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

{

if(a[i]>x)

{

while(i<j&&a[j]>x)

j--;

if(i!=j){

int t=a[i];

a[i]=a[j];

a[j]=t;

j--;

}

}

}

return i-1;

}

int select(int p,int r,int k) //寻找中位数

{

if(r-p<5){

bubble(p,r);

return a[p+k-1];

}

for(int i=0;i<(r-p-4)/5;i++)

{

int s=p+5*i,t=s+4;

bubble(s,t);

int temp=a[p+i];

a[p+i]=a[s+2];

a[s+2]=temp;

}

int x=select(p,p+(r-p-4)/5,(r-p+6)/10);

i=partition(p,r,x);

int j=i-p+1;

if(k<=j)

return select(p,i,k);

else

return select(i+1,r,k-j);

}

};

void main()

{

clock_t start,end;

double elapsed;

srand((int)time(NULL));

for(int k=0;k<N;k++)

{

a[k]=random();

cout<<a[k]<<"\t";

}

cout<<endl;

start=clock();

Find f;

int n=5000;

cout<<"The No."<<n<<" is :"<<f.select(0,N-1,n)<<endl;

end=clock();

elapsed=((double)(end-start));///CLOCKS_PER_SEC;

cout<<"Time: "<<elapsed<<endl;

}
...全文
280 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
littlr 2011-06-06
  • 打赏
  • 举报
回复
不知道楼主把这个问题搞明白了没有?
为什么“
for(int i=0;i<(r-p-4)/5;i++)
这里为什么要减去4,
int x=select(p,p+(r-p-4)/5,(r-p+6)/10);
为什么又加上6

不解,求解答
asmlearn 2010-11-28
  • 打赏
  • 举报
回复
个人认为,减4是和后面除5对应的,加6是和后面除10对应的。
allantop 2010-11-28
  • 打赏
  • 举报
回复
还有谁能把上面的那个代码拿回去跑一下,现在我发现他那个代码有些问题,patiton那个函数根本就没有patition的效果。
allantop 2010-11-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 asmlearn 的回复:]

个人认为,减4是和后面除5对应的,加6是和后面除10对应的。
[/Quote]

除以5是这个算法的思想,为什么忽略掉后面4个数不算我就不知道了,算法思想是这样的:
【题目】:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素,(这里给定的线性集是无序的)

【思路】:如果能在线性时间内找到一个划分基准,使得按这个基准所划分出的2个子数组的长度都至少为原数组长度的ε倍(0<ε<1是某个正常数),那么就可以在最坏情况下用O(n)时间完成选择任务。
例如:若ε=9/10,算法递归调用所产生的子数组的长度至少缩短1/10。所以,在最坏情况下,算法所需的计算时间T(n)满足递归式T(n)≤T(9n/10)+O(n) 。由此可得T(n)=O(n)。
【具体解题】:这里我们将所有的数(n个),以每5个划分为一组,共[n/5]组(将不足五个的那组忽略);然后用任意一种排序算法(因为只对五个数进行排序,所以任取一种排序法就可以了,这里我选用冒泡排序),将每组中的元素排好序再分别取每组的中位数,得到[n/5]个中位数;再取这[n/5]个中位数的中位数(如果n/5是偶数,就找它的2个中位数中较大的一个)作为划分基准,将全部的数划分为两个部分,小于基准的在左边,大于等于基准的放右边。
在这种情况下,找出的基准x至少比3(n-5)/10个元素大,因为在每一组中有2个元素小于本组的中位数,中位数处于1/2*[n/5-1],即n/5个中位数中又有(n-5)/10个小于基准x。同理,基准x也至少比3(n-5)/10个元素小。而当n≥75时,3(n-5)/10≥n/4所以按此基准划分所得的2个子数组的长度都至少缩短1/4。

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧