在一个有序数列中查找,二分查找是最优算法吗?怎样证明?

zhaokai115 2016-06-08 08:16:05
假设对这个数列进行x分查找,即每次取1/x位置上的数,判断要找的数在它的哪一边子区间,然后再在这个子区间进行x分查找,计算平均需要查找的数目。

对二分查找,x=2,平均需要查找log2(n) = ln(n) / ln(2) 次,计算过程略。

如果是三分查找,x=3,则要找的数有1/3的几率落在小子区间内,2/3的几率落在大子区间内,这样每次比较,
1)因为有1/3的几率淘汰2/3的数据,2/3的几率淘汰1/3的数据,所以平均剩下1/3*1/3+2/3*2/3=5/9
共需要比较ln(n)/ln(9/5)次 ~= 1.7 * ln(n)
2)平均每3次比较,有一次淘汰2/3的数据,2次淘汰1/3的数据,所以3次后剩下1/3*2/3*2/3=4/27
共需要比较3 * ln(n)/ln(27/4)次 ~= 1.57 * ln(n)

为什么两种方法计算结果不一样?对通常的x又该用哪种方法计算?
...全文
964 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
tanta 2016-07-07
  • 打赏
  • 举报
回复
直接的二分一定不是最优的。 按照概率的二分才是最优的。实际上,我们希望尽可能找到该数在整个数列中最大出现可能的位置。 比如说,有一串数列共100个元素,最小值1,最大值100,随机分布,要查找90,直接查找第90个元素,是可能性最大的。 再比如说,一串数列,满足一定分布规律,那要根据分布规律去找。
FancyMouse 2016-06-18
  • 打赏
  • 举报
回复
1和2没一个对的。假设查询均匀随机,长度为n的期望查找次数是f(n),那递推式是f(n)=1/3*f(n/3)+2/3*f(2n/3)+1。这个解出来f(n)=c*log(n),c满足1/c=1/3*log(3)+2/3*log(3/2)。
iceberg2271 2016-06-08
  • 打赏
  • 举报
回复
这个应该是这样的,但是感觉有概率,2分法是以2的次方能够缩减数据长度的,而1/x是概率性的以1/x到x-1/x缩小数据的。 你的思路应该是对的,因为这个是出现次数相同的情况应该是以下概率,
zhaokai115 2016-06-08
  • 打赏
  • 举报
回复
如果第一种算法是对的,对x分查找,一次比较后,还剩下1/x * 1/x + (x-1)/x * (x-1) / x = (x^2 - 2x + 2) / x^2 求导数得到 2x * (x - 2) / x^4 当x=2时有极值
iceberg2271 2016-06-08
  • 打赏
  • 举报
回复
补充一下,假如是4和2分,那么只要不是1/4处出现那么分法就是麻烦的,就是说数据不在最开始的1/4的话那么第一次判断就相当于只将数据缩小了1/4,2分法是1/2。。。。就是这个意思=-=
iceberg2271 2016-06-08
  • 打赏
  • 举报
回复
应该是最优,只是感觉上的 假设为x分法,那么按照LZ你所说的选点问题,如果出现在第一个区间点则当然是最为乐观的情况,但是这种概率也是1/x,而大概率会出现在不是1/x的地方,然而当出现了超过1/2处时依旧还在排序时,那么算法时间复杂就已经高于2分了,因为2分是1次能够将数据分成2分大小,而1/x分当大于一个1/2时算法是失败的,因为你进行了x/2-1次判断,最后得出的还是1/2区间的大小。

33,008

社区成员

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

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