二分查找及扩展

面试常让写二分查找或其扩展的程序,以前总觉得很简单,但是真动手写起来,细节很多,容易出错的地方也很多,真是秒杀眼高手低的利器,本节就二分查找以及相关扩展程序都实现一下,同时将可能出错的地方以及需要注意的细节也一并说明,水平有限,欢迎补充。

内容如下:

1)二分查找元素key的下标,如无 return -1

2)二分查找返回key(可能有重复)第一次出现的下标,如无return -1

3)二分查找返回key(可能有重复)最后一次出现的下标,如无return -1

4)二分查找返回刚好小于key的元素下标,如无return -1

5)二分查找返回刚好大于key的元素下标,如无return -1


http://www.ahathinking.com/archives/179.html

看了这个写的后觉得很难理解, 自己写了一个  

1)二分查找元素key的下标,如无 return -1

 

#include <stdio.h>
#define ARRAY_LEN(array) sizeof(array)/sizeof(array[0])

int is_sort_asc(int array[], int length)
{
	int i = 0;
	if(length <= 0)
	{
		return -1;
	}
	for(i = 0; i < length - 1; i++) --------------------------------------->注意条件
	{
		if(array[i] > array[i+1])
		{
			return -1;
		}
	}
	return 0;
}


int binary_search(int array[], int left, int right, int key)
{
	int mid = 0;
	if(right <= 0)
	{
		return -1;
	}
	
	while(left <= right)     --------------------------------------->注意条件
	{
		printf("left = %d, right = %d\n", left, right);
		mid = (left + right) >> 1;                              /*更好的写法是 mid = left + ((right - left) >> 1)*/
		printf("mid = %d, array[mid] = %d\n", mid, array[mid]);
		if(array[mid] < key)	
		{
			left = mid + 1;
		}
		else if(array[mid] > key)
		{
			right = mid - 1;
		}	
		else
		{
			return mid;
		}
	}
	return -1;
}
int main()
{
	int tmp[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
	int num = 0;
	int i = 0;
	int ret = -1;
	printf("tmp array:");
	for(i = 0; i < ARRAY_LEN(tmp); i++)
	{
		printf(" %d", tmp[i]);
	}
	printf("\n");
	if(-1 == is_sort_asc(tmp, ARRAY_LEN(tmp)))
	{
		printf("tmp is not sort by asc\n");
		return -1;
	}

	num = 1;
	ret = binary_search(tmp, 0, ARRAY_LEN(tmp) - 1, num);
	if(-1 == ret)
	{
		printf("can not find the num %d\n", num);
	}
	else
	{
		printf("find key = %d in tmp[%d]\n", num, ret);
	}
	printf("\n");
	return 0;
}


2)二分查找返回key(可能有重复)第一次出现的下标,如无return -1

 

 

int binary_search(int array[], int left, int right, int key)
{
	int mid = 0;
	if(right <= 0)
	{
		return -1;
	}
	
	while(left <= right)
	{
		printf("left = %d, right = %d\n", left, right);
		mid = (left + right) >> 1;
		printf("mid = %d, array[mid] = %d\n", mid, array[mid]);
		if(array[mid] < key)	
		{
			left = mid + 1;
		}
		else if(array[mid] > key)
		{
			right = mid - 1;
		}	
		else
		{
			while(mid >= 1) --------------------------->注意条件
			{
				if(array[mid] == array[mid-1])
				{
					mid -= 1;
				}
				else
				{
					break;
				}
			}
			return mid;
		}
	}
	return -1;
}


4)二分查找返回刚好小于key的元素下标,如无return -1

 

 

int binary_search(int array[], int left, int right, int key)
{
	int mid = 0;
	if(right <= 0)
	{
		return -1;
	}
	
	while(left <= right)
	{
		printf("left = %d, right = %d\n", left, right);
		mid = (left + right) >> 1;
		printf("mid = %d, array[mid] = %d\n", mid, array[mid]);
		if(array[mid] < key)	
		{
			left = mid + 1;
		}
		else if(array[mid] > key)
		{
			right = mid - 1;
		}	
		else
		{
			while(mid >= 1) --------------------------->注意条件
			{
				if(array[mid] == array[mid-1])
				{
					mid -= 1;
				}
				else
				{
					break;
				}
			}
			return mid - 1; /*查找到是第一个元素 直接找不到小于它的索引*/
		}
	}
	return -1;
}


任意组合这几种条件, 欢迎高手拍砖。

 

 

posted @ 2013-07-05 21:54  爱生活,爱编程  阅读(269)  评论(0编辑  收藏  举报