免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5404 | 回复: 15
打印 上一主题 下一主题

请教:用最少的比较次数求一个数组第二最小值 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-02-17 20:22 |只看该作者 |倒序浏览
给定数组A,怎样能用最少的比较次数能解决寻找第二最小值,并给出最坏情况下所用的比较次数,注意,这里不是问算法的时间复杂性,问的也不是数量级,而是具体的最坏强况下最小比较次数

[ 本帖最后由 fsilence 于 2006-2-17 20:31 编辑 ]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2006-02-17 20:42 |只看该作者
好久没有写 C code 了。
试试看:
  1. 因为楼主在要作业,所以我屏蔽掉了
复制代码

[ 本帖最后由 flw 于 2006-2-17 21:11 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2006-02-17 21:01 |只看该作者
给个大概的算法描述吧
把数组两两分组,如果数组大小为奇数,最后一个另外考虑
设 b为最大,a为次大
每次扫描到  (A_i,A_(i+1))
比较A_i和A_(i+1),设其中大的为y,小的为x,

如果y>b,则次大应为x和b里大的
如果y<=b,则次大应为y和a里大的

这样每对(A_i,A_(i+1))最多要3次比较

而如果剩下一个A_i,最多比较2次

所以最坏情况时数组大小为偶数,比较次数为3*n/2

PS:楼上兄弟的要2*n次吧...

评分

参与人数 1可用积分 +1 收起 理由
win_hate + 1 我很赞同

查看全部评分

论坛徽章:
0
4 [报告]
发表于 2006-02-17 21:07 |只看该作者
汗...上面的算法改最大成最小就行了...
最近老是看错...

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
5 [报告]
发表于 2006-02-17 21:10 |只看该作者
原帖由 ArXoR 于 2006-2-17 21:07 发表
汗...上面的算法改最大成最小就行了...
最近老是看错...

不是你看错了,
是楼主改帖子了。由此可见,这个问题是个作业题,他发错了,又不会举一反三,因此重新改了,希望大家能给他一个准确的答案。
有鉴于此,我把我的帖子也编辑掉吧。

论坛徽章:
0
6 [报告]
发表于 2006-02-18 07:59 |只看该作者
原帖由 fsilence 于 2006-2-17 04:22 发表
给定数组A,怎样能用最少的比较次数能解决寻找第二最小值,并给出最坏情况下所用的比较次数,注意,这里不是问算法的时间复杂性,问的也不是数量级,而是具体的最坏强况下最小比较次数


答案是 n + ceil(log n) -2
ceil 是上取整,log以2为底,至于为什么,楼主自己悟吧。。

论坛徽章:
0
7 [报告]
发表于 2006-02-18 09:47 |只看该作者
这个怎么样?


  1. #include <stdio.h>
  2. #include <time.h>

  3. int main(){
  4.         int a[10];
  5.         int i;
  6.         //init a[10]
  7.         int max,smax;
  8.         srand(time(0));
  9.         for(i=0;i<10;i++){
  10.                 a[i] = rand()%100;
  11.                 printf("%d ",a[i]);
  12.         }
  13.         printf("\n");
  14.        

  15.         max = a[0];
  16.         if(a[0] < a[1]) smax = a[1];
  17.         else smax = a[0];
  18.         for(i = 0;i<10;i++){
  19.                 if(a[i] < max){
  20.                         smax = max;
  21.                         max = a[i];
  22.                 }
  23.                 else if(a[i] < smax) smax = a[i];
  24.         }
  25.         printf("max=%d; smax=%d;\n",max,smax);
  26.         return 1;
  27. }
复制代码

[ 本帖最后由 ideawu 于 2006-2-18 09:52 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2006-02-18 10:25 |只看该作者
原帖由 emacsnw 于 2006-2-17 15:59 发表


答案是 n + ceil(log n) -2
ceil 是上取整,log以2为底,至于为什么,楼主自己悟吧。。


厚道点,还是说吧。。其实方法很简单:
对n个数两两比较,即a[0] vs a[1], a[2] vs a[3],... 最后还有多的就轮空,每次比较的较小值“获胜”进入下一轮;
对最多ceil(n/2)个“获胜”者继续上述两两比较,知道最后决出“冠军”,这就是n个数的最小值。
我想很容易得知,这样得到最小值共进行了 n-1 次比较操作。

关键是:第二小的数一定是所有与最小值进行过比较的那些数中间的最小值。由于最小值一共进行了 ceil(log n)次比较,因此我们有 ceil(log n)个candidates. 从这么多数里找最小值需要的比较次数当然是 ceil(log n)-1。

总共需要的比较次数因此是 n + ceil(log n) - 2

评分

参与人数 1可用积分 +2 收起 理由
win_hate + 2 我很赞同

查看全部评分

论坛徽章:
0
9 [报告]
发表于 2006-02-18 11:17 |只看该作者
原帖由 emacsnw 于 2006-2-18 10:25 发表


厚道点,还是说吧。。其实方法很简单:
对n个数两两比较,即a[0] vs a[1], a[2] vs a[3],... 最后还有多的就轮空,每次比较的较小值“获胜”进入下一轮;
对最多ceil(n/2)个“获胜”者继续上述两两比较,知 ...

这个是不是需要有O(n)额外空间的支持?不然如何记录中间结果呢?
ArXoR的方法是可行的

论坛徽章:
0
10 [报告]
发表于 2006-02-18 11:30 |只看该作者
原帖由 yzc2002 于 2006-2-17 19:17 发表

这个是不是需要有O(n)额外空间的支持?不然如何记录中间结果呢?
ArXoR的方法是可行的


ArXoR的方法是可行的,但是题目好像只要求最少的比较次数,没说不能使用额外空间。
毕竟 n + log(n) 要比 1.5n 小很多。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP