算法复习笔记:二分查找
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法复习笔记:二分查找相关的知识,希望对你有一定的参考价值。
在计算机科学中,折半搜索(英语:half-interval search),也称二分查找算法(binary search)、二分搜索法、二分搜索、二分探索,是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
实现:
int binarySearch(vector<int> &v,int x) { int left = 0; int right = v.size() -1; while(left <= right) { int mid = left + ((right - left)>>1); if(v[mid] == x) return mid; else if(v[mid] < x) left = mid + 1; else right = mid - 1; } return -1; }
注意问题
- 区间开闭。left和right表示算法当前处理的数组的最小下标和最大下标,上述采用闭区间[0,v.size()-1]。采用闭区间的判断条件为left<=right,如果用left<right在最后一个元素是会直接跳出[left,left]。
- 中间下标计算。平均值计算能出现除法性能较低,加法可能溢出采用mid = left + ((right - left)>>1)计算可避免。
- 下标修改。采用+1-1修改的方式,修改之后新的区间肯定不会跟原区间一样,算法不会进入死循环。
查找第一次出现
在v的当前区间[left,right]中,数据为非递减序, 如果tar<=v[mid],则v[mid]右边的元素(不包括v[mid])全部都不符合要求 ,则right = mid;如果tar > v[mid], 则左边的元素包括v[mid]全部都小于tar,则left = mid +1; 此时循环条件在最后一个元素的时候,会出现死循环,需要改成left<right。
比如:
当前状况: tar == V[0], left == 0,right == 0
计算: mid = 0
更新: 更新right = mid = 0;
int binarySearchFirst(vector<int> & v,int x) { int left = 0; int right = v.size()-1; while(left < right) { int mid = left + ((right - left)>>1); if(x <= v[mid]) right = mid; else left = mid + 1; } if(v[left] == x) return left; else return -1; }
查找最后一次出现
在v的当前区间[left,right]中,数据为非递减序, 如果tar<v[mid],则v[mid]以及右边的元素全部都不符合要求 ,则right = mid - 1;如果tar >= v[mid], 则左边的元素v[mid]全部都小于tar,则left = mid ; 但是在最后两个元素的时候,循环会一直保持不变,所以采取的方法是 int mid = left + ((right - left + 1)>>1);
比如:
当前状况: tar == V[0], left == 0,right == 1
计算: mid = 0
更新: 更新left = mid = 0;
int binarySearchLast(vector<int> &v,int x) { int left = 0; int right = v.size()-1; while(left < right) { int mid = left + ((right - left + 1)>>1); if(x < v[mid]) right = mid - 1; else left = mid ; } if(v[left] == x) return left; else return -1; }
以上是关于算法复习笔记:二分查找的主要内容,如果未能解决你的问题,请参考以下文章