现在的位置: 首页 > 综合 > 正文

二分查找

2012年06月18日 ⁄ 综合 ⁄ 共 1180字 ⁄ 字号 评论关闭

        二分查找是对已经排序好的序列进行查找。因为这个程序非常经典地简单又容易出错,所以在当着面试官纸上写程序的场合这个程序的命中率非常高。

        源码如下:

#include <iostream>
using std::cout;
using std::endl;

//xk> 二分查找
//xk>--------------------------------------------------
// 返回value在数组A中的索引
int
binarySearch(int A[], int N, int value)
{
	int low = 0;
	int high = N - 1;
	int mid;

	while(low <= high){
		// mid = (low + high) / 2;	// 这种写法容易溢出
		mid = low + ((high - low) >> 1);
		if(A[mid] > value)
		{
			high = mid - 1;
		}else if(A[mid] < value){
			low = mid + 1;
		}else{
			return mid;
		}
	}
	
	return -1;
}

int
main()
{
	int A[] = {0, 1, 2, 3, 4, 5, 6, 7};

	int n = binarySearch(A, 8, 4);
	cout << n << endl;

	return 0;
}

        上面的程序只是简单地实现了最基本的二分查找。下面来个高端的:

        找出一个有序(字典序)字符串数组arr中值等于字符串v的元素的序号,如果有多个元素满足这个条件,则返回其中序号最大的。

        int binSearch(char **arr, int b, int e, char *v);

#include <iostream>
using std::cout;
using std::endl;

int
binSearch(char **arr, int min, int max, char *v)
{
	int mid;
	//xk> 注意防止终止条件不可达
	// 若min为偶数,终止条件为min == max
	// 若min为奇数,终止条件为min == max - 1
	// while(min < max)或while(min <= max)都会出现死循环
	while(min < max - 1){
		//xk> 注意防止溢出
		mid = min + (max - min) >> 1;
		//xk> 因为要返回最大的序号,优先移动min,并且=0时也要继续移动
		if(strcmp(arr[mid], v) <= 0){
			//error> min = mid + 1;
			// 因为判断条件是<=0, 在等于时也会移动min
			// 这里不能加1,否则可能跳过已找到的,返回-1
			min = mid;
		}
		else{
			// 这里也不需要减1
			max = mid;
		}
	}
	if(!strcmp(arr[max], v)){
		return max;
	}else if(!strcmp(arr[min], v)){
		return min;
	}else{
		return -1;
	}
}

void
main()
{
	// 设计测试用例
}

抱歉!评论已关闭.