c语言实现二分搜索算法

来源:互联网 发布:java接口防止重复调用 编辑:程序博客网 时间:2024/06/06 20:45

二分搜索针对有序的数组,每次和中间元素比较,如果相等则直接返回,如果不相等则搜索范围可以减半。二分法可以将复杂度从 Ο(n) 降到 Ο(log n)。 本来以为二分法很简单,半分钟搞定,但写起来尼玛才发现不是这里有点问题,就是那里有问题。

针对整数的二分搜索

直接上代码:

  1. int binary_search(int data[], int n, int x)
  2. {
  3. if(n <= 0 || x < data[0] || x > data[n-1]){
  4. return -1;
  5. }
  6. int left = 0, right = n-1;
  7. int middle;
  8. while(left <= right){
  9. middle = (left + right)/2;
  10. if(x == data[middle]){
  11. return middle;
  12. }else if(x > data[middle]){
  13. left = middle + 1;
  14. }else{
  15. right = middle - 1;
  16. }
  17. }
  18. return -1;
  19. }

上面假定的 data 是按升序排列。

通用的二分搜索算法

  1. #include <stdio.h>
  2. #include <assert.h>
  3. int binary_search(void *data, int n, int size, void *ele, int(*cmp)(void*, void*))
  4. {
  5. if(n <= 0 || (*cmp)(ele, data) < 0 || (*cmp)(data+(n-1)*size, ele) < 0){
  6. return -1;
  7. }
  8. int left = 0, right = n-1;
  9. int middle;
  10. while(left <= right){
  11. middle = (left + right)/2;
  12. if((*cmp)(ele, data+size*middle) == 0){
  13. return middle;
  14. }else if((*cmp)(data+size*middle, ele) < 0){
  15. left = middle + 1;
  16. }else{
  17. right = middle - 1;
  18. }
  19. }
  20. return -1;
  21. }
  22. int cmp_int(void *a, void *b){
  23. return *(int*)a - *(int*)b;
  24. }
  25. int main()
  26. {
  27. int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  28. int x = 3;
  29. int index = binary_search(data, 10, sizeof(int), &x, cmp_int);
  30. printf("%d\n", index); // 2
  31. return 0;
  32. }

通用的版本有些奇葩,多处用到 void*, 这是 c 的常用伎俩。如果使用 c++ 模板的话也会好很多。

标准库算法

c 的 stdlib.h 头文件提供了一个二分搜索函数: void *bsearch(const void *key, const void *base, size_t nmem, size_t size, int (*comp)(const void *, const void *)); 和上面的原型大体一样,只是顺序不同而已。

c++ 的二分搜索:bool binary_search (ForwardIterator first, ForwardIterator last, const T& val);

0 0
原创粉丝点击