面试常让写二分查找或其扩展的程序,以前总觉得很简单,但是真动手写起来,细节很多,容易出错的地方也很多,真是秒杀眼高手低的利器,本节就二分查找以及相关扩展程序都实现一下,同时将可能出错的地方以及需要注意的细节也一并说明,水平有限,欢迎补充。
内容如下:
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;
- }
任意组合这几种条件, 欢迎高手拍砖。