数据结构之二分查找

Posted 小杰IT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构之二分查找相关的知识,希望对你有一定的参考价值。

二分查找针对的是一个有序的数据集合,查找思想有点类似分治思想。每次都通过跟区间中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。

二分查找是一种非常高效的查找算法,时间复杂度为O(logn)

二分查找代码递归实现:

 public int BinarySearch(int[] arr, int i, int start, int end) { int mid; while (start <= end) { mid = (start + end) / 2; if (arr[mid] == i) { return mid + 1; } else if (arr[mid] < i) { return fun(arr, i, mid + 1, end); } else { return fun(arr, i, start, mid - 1); } } return -1;  }

二分查找代码非递归实现:

  public int BinarySearch (int[] arr, int i) { int start = 0; int end = arr.length - 1; int mid; while (start <= end) { mid = (start + end) / 2; if (arr[mid] == i) { return mid + 1; } else if (arr[mid] < i) { start = mid + 1; } else { end = mid - 1; } } return -1;  }

这只是二分查找中最简单的一种情况,在不存在重复元素的有序数组中,查找值等于给定值的元素。最简单的二分查找不难,但是,二分查找的变形问题就比较难了。

变体一:查找第一个值等于给定值的元素

代码实现:

 public int bsearch(int[] a, int n, int value) { int low = 0; int high = n - 1; while (low <= high) { int mid = low + ((high - low) >> 1); if (a[mid] > value) { high = mid - 1; } else if (a[mid] < value) { low = mid + 1; } else { if ((mid == 0) || (a[mid - 1] != value)) return mid; else high = mid - 1; } } return -1; }

    a[mid] 跟要查找的 value 的大小关系有三种情况:大于、小

于、等于。如果我们查找的是任意一个值等于给定值的元素,当 a[mid] 等于要查找的值时,a[mid]就是我们要找的元素。但是,如果我们求解的是第一个值等于给定值的元素,当 a[mid]等于要查找的值时,我们就需要确认一下这个 a[mid] 是不是第一个值等于给定值的元素。

如果 mid 等于 0,那这个元素已经是数组的第一个元素,那它肯定是我们要找的;如果 mid 不等于 0,但 a[mid] 的前一个元素 a[mid-1] 不等于value,那也说明 a[mid] 就是我们要找的第一个值等于给定值的元素。

如果经过检查之后发现 a[mid] 前面的一个元素 a[mid-1] 也等于 value,那说明此时的a[mid] 肯定不是我们要查找的第一个值等于给定值的元素。那我们就更新 high=mid-1,因为要找的元素肯定出现在 [low, mid-1] 之间。

变体二:查找最后一个值等于给定值的元素

代码实现:

public int bsearch(int[] a, int n, int value) { int low = 0; int high = n - 1; while (low <= high) { int mid = low + ((high - low) >> 1); if (a[mid] > value) { high = mid - 1; } else if (a[mid] < value) { low = mid + 1; } else {        if ((mid == arr.length-1) || (a[mid + 1] != value)) return mid; else high = mid - 1; } } return -1; }

变体三:查找第一个大于等于给定值的元素

  public int binarySearch(int[] arr, int value) { int low=0; int high=arr.length-1; while(low<=high){ int mid=low +((high-low)/2); if(arr[mid]>=value){ if(mid==0||(arr[mid-1]<value)){ return mid; }else{ high=mid-1; } }else{ low=mid+1; } } return -1;  }

变体四:查找最后一个小于等于给定值的元素

 private static int binarySearch(int[] arr, int value) { int low=0; int high=arr.length-1; while(low<=high){ int mid=low +((high-low)/2); if(arr[mid]<=value){ if(mid==arr.length-1||(arr[mid+1]>value)){ return mid; }else{ low=mid+1; } }else{ high=mid-1; } } return -1; }


以上是关于数据结构之二分查找的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法之-二分查找

基础算法模板之二分

python算法之二分查找

java实现二分查找

SDUT 3376 数据结构实验之查找四:二分查找

Python 算法之二分查找