binary search - c (simple)
search - basic:
/** @author kuchaguangjie@gmail.com */
#include <stdio.h>
/**
* binary search (simple)
*
* @param
* arr pointer of array
* @param
* len length of array
* @param
* x target to search
*
* @return
index of target in the array,return -1 if not found,
*/
int bin_search(int *arr,int len,int x) {
// indexs
int start = 0,end = len-1,middle;
while (end >= start) {
middle = (start + end) >> 1;
if (*(arr+middle)==x) {
return middle;
} else if(x < *(arr+middle)) {
end = middle - 1;
} else {
start = middle + 1;
}
}
// not found
return -1;
}
int main() {
int arr_1[8] = {0,1,3,4,6,7,9,10};
int i_1 = bin_search(arr_1,8,3);
int i_2 = bin_search(arr_1,8,9);
int i_3 = bin_search(arr_1,8,5);
int i_4 = bin_search(arr_1,8,15);
int i_5 = bin_search(arr_1,8,-5);
printf("expect:\n\t2,6,-1,-1,-1\n");
printf("actural:\n\t%d,%d,%d,%d,%d\n",i_1,i_2,i_3,i_4,i_5);
}
search - first / last / all
/** @author kuchaguangjie@gmail.com */
#include <stdio.h>
/**
* binary search, search the first match,
*
* @param
* arr pointer of array
* @param
* len length of array
* @param
* x target to search
*
* @return
index where target first appear in the array,return -1 if not found,
*/
int bin_search_first(int *arr,int len,int x) {
// indexs
int start = 0,end = len-1,middle;
while (end > start) { // here must be '>', not '>=', otherwise endless loop might happen,
middle = (start + end) >> 1;
if(*(arr+middle) < x) {
start = middle + 1;
} else {
end = middle;
}
}
if(*(arr+start) == x) {
return start;
} else {
// not found
return -1;
}
}
int test_search_first() {
int len = 17;
int arr_1[17] = {0,1,3,4,6,7,7,7,7,7,7,7,7,7,7,9,10};
int i_0 = bin_search_first(arr_1,len,7);
int i_1 = bin_search_first(arr_1,len,3);
int i_2 = bin_search_first(arr_1,len,9);
int i_3 = bin_search_first(arr_1,len,5);
int i_4 = bin_search_first(arr_1,len,15);
int i_5 = bin_search_first(arr_1,len,-5);
printf("expect:\n\t5,2,15,-1,-1,-1\n");
printf("actural:\n\t%d,%d,%d,%d,%d,%d\n",i_0,i_1,i_2,i_3,i_4,i_5);
}
/**
* binary search, search the last match,
*
* @param
* arr pointer of array
* @param
* len length of array
* @param
* x target to search
*
* @return
index where target last appear in the array,return -1 if not found,
*/
int bin_search_last(int *arr,int len,int x) {
// indexs
int start = 0,end = len-1,middle;
while (end > start) { // here must be '>', not '>=', otherwise endless loop might happen,
middle = (start + end + 1) >> 1; // here must be '(start + end + 1)', not '(start + end)', otherwise endless loop might happen,
if(*(arr+middle) > x) {
end = middle - 1;
} else {
start = middle;
}
}
if(*(arr+end) == x) {
return end;
} else {
// not found
return -1;
}
}
int test_search_last() {
int len = 17;
int arr_1[17] = {0,1,3,4,6,7,7,7,7,7,7,7,7,7,7,9,10};
int i_0 = bin_search_last(arr_1,len,7);
int i_1 = bin_search_last(arr_1,len,3);
int i_2 = bin_search_last(arr_1,len,9);
int i_3 = bin_search_last(arr_1,len,5);
int i_4 = bin_search_last(arr_1,len,15);
int i_5 = bin_search_last(arr_1,len,-5);
printf("expect:\n\t14,2,15,-1,-1,-1\n");
printf("actural:\n\t%d,%d,%d,%d,%d,%d\n",i_0,i_1,i_2,i_3,i_4,i_5);
}
/**
* result of search all match,
* first is the index of first match, -1 means no match
* last is the index of last match, -1 means no match
* count is the count of match,
*/
typedef struct {int first, last, count;} all_result;
/**
* binary search, search all match,
* steps:
* first search a match,
* if not found, then return, over,
* if found,
divide the array into 2 part by the found match,
search in left part for the first match,and search in the right part for the last match,
then combine them, that's the result,
*
* @param
* arr pointer of array
* @param
* len length of array
* @param
* x target to search
*
* @return
type all_result
*/
all_result * bin_search_all(int *arr,int len,int x) {
// indexs
int start = 0,end = len-1,middle;
static all_result result;
result.first = -1;result.last = -1;result.count = 0; // this is a static variable, init it every time,
while (end >= start) {
middle = (start + end) >> 1;
if (*(arr+middle)==x) { // find a match
result.first = bin_search_first(arr+start,middle-start+1,x)+start;
result.last = bin_search_last(arr+middle, end-middle+1,x)+middle;
result.count = result.last - result.first + 1;
return &result;
} else if(x < *(arr+middle)) {
end = middle - 1;
} else {
start = middle + 1;
}
}
return &result;
}
int test_search_all() {
int len = 17;
int arr_1[17] = {0,1,3,4,6,7,7,7,7,7,7,7,7,7,7,9,10};
all_result *r_0 = bin_search_all(arr_1,len,7);
printf("r_0\texpect: [5, 14]:10,\tactrual: [%d, %d]:%d\n",r_0->first,r_0->last,r_0->count);
all_result *r_1 = bin_search_all(arr_1,len,3);
printf("r_1\texpect: [2, 2]:1,\tactrual: [%d, %d]:%d\n",r_1->first,r_1->last,r_1->count);
all_result *r_2 = bin_search_all(arr_1,len,9);
printf("r_2\texpect: [15, 15]:1,\tactrual: [%d, %d]:%d\n",r_2->first,r_2->last,r_2->count);
all_result *r_3 = bin_search_all(arr_1,len,5);
printf("r_3\texpect: [-1, -1]:0,\tactrual: [%d, %d]:%d\n",r_3->first,r_3->last,r_3->count);
all_result *r_4 = bin_search_all(arr_1,len,15);
printf("r_4\texpect: [-1, -1]:0,\tactrual: [%d, %d]:%d\n",r_4->first,r_4->last,r_4->count);
all_result *r_5 = bin_search_all(arr_1,len,-5);
printf("r_5\texpect: [-1, -1]:0,\tactrual: [%d, %d]:%d\n",r_5->first,r_5->last,r_5->count);
}
int main() {
test_search_all();
}

本文深入探讨了二分搜索算法的不同实现方式,包括简单的查找、寻找目标首次及最后一次出现的位置,以及返回所有匹配项的范围与数量。通过具体的代码示例展示了如何在已排序数组中高效地查找指定元素。
379

被折叠的 条评论
为什么被折叠?



