博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

编程之美 3.11程序改错(你会写二分查找吗?)

Posted on 2011-09-14 21:07  各种不会  阅读(1068)  评论(0)    收藏  举报

没想到啊,没想到啊,写个二分查找竟然写的很不利索,主要是边界问题啊,特别是当mid元素等于待找元素的时候。反正不管怎么样吧,纠结了一下子之后还是把代码写好了,不知道还有没有BUG。通过这个题目,感觉到在写比较复杂的循环的时候,还是把循环的循环不变式写出来,比较有帮助,能让自己更加清楚的看清楚各个边界条件的处理和自己所写循环是否能完成既定的任务。

#include "stdafx.h"
#include <iostream>

using namespace std;

//求任意一个position使得datas[position]==num,找不到返回-1
int BinarySearch(int *datas, int l, int r, int num){
	int mid, position=-1;
	while (true)
	{
		if(l>r)
			break;
		mid = l+(r-l)/2;
		if(num>datas[mid])
			l = mid+1;
		else if(num == datas[mid]){
			position=mid;
			break;
		}
		else 
			r = mid-1;
	}
	return position;
}

//求最大(最小)的position使得datas[position]==num,找不到返回-1
int BinarySearch1(int *datas, int l, int r, int num){
	int mid, position = -1;
	while (true)
	{
		if(l==r-1)
			break;
		mid = l+(r-l)/2;
		if(num > datas[mid])
			l=mid+1;
		else if(num == datas[mid])
			l = mid;
		else
			r = mid-1;
	}
	if(datas[r]==num)
		position = r;
	else if(datas[l] == num)
		position = l;
	return position;
}

//求最小(最大)的position使得datas[position] >(<) num, 找不到返回-1;
int BinarySearch2(int *datas, int l, int r, int num){
	int mid, pos = -1; int maxr = r;
	while (true)
	{
		if(l>r)
			break;
		mid = l+(r-l)/2;
		if(num >= datas[mid])//此时找最小的p使得datas[position] >num,若将等号去掉就是求最大的position使得datas[position] < num
			l= mid+1;        //关键就是在相等时候要特别注意;
		else
			r = mid-1;
	}
	//当循环结束之后必然是d[r]<num, d[l]>num
	if(l<=maxr)
		pos = l;
	else
		pos = -1;
	return pos;
}

int main(int argc, char* argv[])
{
	int datas[] = {1,2,3,5,7,7};
	cout << BinarySearch2(datas,0,sizeof(datas)/sizeof(datas[0]), 7) << endl;
	return 0;
}

 不知道是自己太笨,还是怎么回事,反正我老是在这种循环的边界条件上要纠结好久。。。太囧了。。。大一就学过的小程序,到现在还写的马马虎虎的,很痛心啊!