研究二分搜索算法

二分搜索的深入研究

(特别提醒,我喜欢大家关注文章本身,而不是我的排版~,虽然咱的文章没人看,但也要友好提示~)
直接进入正题,节约大家时间,二分搜索简单的我都不好意思来写,但是为了循序渐进的来,还是一步一个脚印子实在!哈哈

先说下为什么要用二分搜索,直接通俗的例子就是~你和我玩游戏,如果你心里想出来一个数字,让你猜我想的是多少?你每次猜过,我都提示你,你所猜的数字与我想的
数字的大小关系,比如我们俩规定我想一个100以内的数字,比如我想的是37,你首先会猜50,我说大了,你猜25,我说小了,直至你将我所猜的数字答出为止。
  • 这肯定要比你直接从1问到100来猜我所想的数字快的多的多。那么如果你每次猜中间,大约几次能猜出答案呢?
很简单我们粗略来算,太精确也没多少意义,100>2^6 (我真心不会排版!100大于2的6次方) 100< 2^7。
	关键的一句是① ,它表明什么?由于100小于128,对于128来说,你运气再差也应该在7次内找到我所想的数字,因为每次二分切割128都会除以2,那么他除以2七次也就是等于1,也就是说经过7次筛选就剩下一个数字,那么这一个就是答案。
	
	所以我们可以粗略的来统计,如果按照这样的查找,N个已排序的数据来说  2^m-1<N<=2^m	m的取值范围我就不详细写了,数学内容我尽量写出核心而不是严谨,太严谨就太枯燥了。 由于对数函数lg(以后我的lg表示以2为底)是单调递增的函数(f(x)单调递增就是说p>q则f(p)>f(q),  f(p)>f(q)则p>q,可以下个软件看下对数函数的图形表示,不解释了。),所以 lg2^m-1<lgN<=lg2^m ==>>  m-1<lgN<=m 所以就得出啥子呢?最多查找数字为m次
	

定理哦亲~二分查找在N(设N为 2^m-1<N<=2^m)个排序的数据中查找一个元素最多需要m次。

	上取整函数为:ceiling,也就是最多需要ceiling(lgN)次~ 下次你可以直接拿来用 而不是思前想后,因为我们证明啦。(虽然不是数学的那种形式化的证明,而且也不是非常严谨,但是对于理解足够了。)
 
	也就是说 就算有2^32个已排序的数据,我们也可以在32次之内找出他,运气烂到渣也不过32次就找到了!这就是二分查找的威力之所在,快!快!快!恕我才疏学浅,我没找到比它更快的查找。如果你知道,请告诉我,互相学习~
	缺点很明显喽,数据必须排好序!这也是我们学习排序算法的源动力啊。
 
	我先给出二分搜搜的代码把,java写着比较简单,不用考虑一些内存等杂七杂八的问题。
 
public static int binary_search(int key, int[] a) {//a是排好序的数组,key要找的在数组中的索引,int是返回key在数组索引,没找到返回-1
	int lo = 0; //做个游戏,你猜我心里想的数~ 咱俩规定好,我想的数字的范围~ 自然要初始化这个范围喽,lo和hi
	int hi = a.length - 1;
	while(lo<=hi) {//这个是个关键,等会解释
	//为了便于理解,我在这里加一句循环的不变量(也就是说每次循环我的这句话都成立!):
	//如果这个key在数组中 那么就必然在[lo,hi]这个区间中,你自己分析,每次循环这个不变量都在缩小
	    int mid = lo+(hi-lo)/2;//你脑子里肯定会想,既然要猜就猜中间那个吧~
	    if(key<a[mid]) hi = mid-1; //我回答的是小啦~ 你会咋样?肯定范围缩小啦
	    else if(key>a[mid]) lo = mid+1;//我回答的是大啦~ 我希望我的注释对于你来说是多余的~
	    else return mid; //如果相等就返回了
	}
	return -1;//前面竟然没返回,那肯定是没有喽。
}

循环退出的条件证明:首先你或许会说,如果这个lo>hi了 待查数据的所在的区间肯定是不存在,自然循环就结束了。可是我问你,这个循环会出现死循环吗?也就是说,随着这个循环不停的运行如果数据不存在lo会大于hi吗?

看下代码不就知道啦,如果数据不存在,则每次一的循环都会增加lo 或者减少hi。当lo>hi时,就肯定不存在这个区间中了。总有一天~~会结束!
文中有错得话,强烈欢迎提出,这也是我写博客的核心源动力之一。以后排版会加强,我们先研究思想,再谈算法。
下集我们讨论下:递归吧,我想我对二分搜索还有递归的实现,以及还有很多话要说,还是有点自己的见解在里面的,欢迎来探讨~
下次博客的内容我先说下,你们也好自己研究一下,然后我们探讨,这样提高的快!真心的快!(我的自学经验,毫无保留的说)
第一,实现二分查找的递归算法。
第二,如果数组中(暂时先研究数组吧。。)当然是已经排好序的,我们带查得元素 有重复,比如:0,1,2,3,4,4,4,4,8,9我们目前的二分查找只能随机的找出4的索引,我们要实现能找出这个元素第一次出现的位置,比如这里 位置就是第五个元素,而不是随意的 5 6 7 8位置。
第三,汉诺塔的递归实现,网上资料很多。
第四,约瑟夫的问题程序的解决(你会看到代数分析会让问题有奇解)
第五,欧几里得算法,soeasy~
上面五个问题,大家可以上网查资料,来学习,然后我们探讨~目的只有一个,互相学习,快速进步~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值