二分查找中的编程小问题

待做:leetcode有几道题目涉及到二分查找的变形!

二分查找是很常用的一个小技巧,思想很简单,就是在排序完的数组中不断的折中查找使得效率从O(n)降到O(lgn)。

但是在编程的时候总是会遇到一些小问题:死循环,边界取不到等等。

假设数组含有n个元素,编号0~n-1;

边界问题:

	int i = 0;
	int j = n - 1;
	int v = (i + j) / 2;

因为是折中判断,所以v=(i+j)/2,但是这个取v的方式使得v的
取值范围是[i, j),也就是闭头开尾,也就是 
的值其实是取不到的,如果你还是按照j=n-1的情况,如果target刚好是最后一个数,那么永远都取不到。

死循环:

死循环的原因跟v的取值范围有关,因为v=(i+j)/2在编译器看来是舍弃小数部分。

	while( i <= j)
	{
		v = (i + j)/2;
		if(a[v] == target) {cout<<v<<endl;break;}
		else if(a[v] > target) j = v;
		else i = v;
	}

当i=v, a[v]<target, j=i+1时,就会导致每次ivj都不变,以此导致了死循环。以下版本为个人总结版本,j取n,while内i加1(j不可减1)。

	int i = 0;
	int j = n - 1;
	int v = (i + j) / 2;
	while( i <= j)
	{
		v = (i + j)/2;
		if(a[v] == target) {cout<<v<<endl;break;}
		else if(a[v] > target) j = v - 1;
		else i = v + 1;
	}
  1. //要把握下面几个要点:    
    //right=n-1 => while(left <= right) => right=middle-1;    
    //right=n   => while(left <  right) => right=middle;    
    //middle的计算不能写在while循环外,否则无法得到更新。
  2. //以上的规则在于:要能取到边界值,所以1中left <= right,2中right = middle;
点赞