二分查找的多种实现
来源:互联网 发布:adc0804 51单片机 编辑:程序博客网 时间:2024/06/05 03:11
折半查找(即二分查找)
二分搜索算法:给定排好序的n个元素arr[0:n-1],在这n个元素中找出一特定元素x.
首先比较容易想到的办法是用顺序搜索方法,逐个比较a[0:n-1]中的元素 ,直至找出元素x或搜索遍整个数组后确定x不在其中,这个方法没有很好的利用n个元素已排好序这个条件,因此在最坏情况下,顺序搜索的方法需要O(n)次比较。
而二分搜素搜的基本思想是将n个元素分成个数大致相同的两半,取arr[n/2]与x进行比较,如果x=arr[n/2],则找到x,算法终止。如果x<arr[n/2],则只要在数组arr的左半部继续搜索x。如果x>arr[n/2],则只要在数组arr的右半部继续搜索x。最坏情况下,也只需O(logn)次比较。
二分搜索算法:给定排好序的n个元素arr[0:n-1],在这n个元素中找出一特定元素x.
首先比较容易想到的办法是用顺序搜索方法,逐个比较a[0:n-1]中的元素 ,直至找出元素x或搜索遍整个数组后确定x不在其中,这个方法没有很好的利用n个元素已排好序这个条件,因此在最坏情况下,顺序搜索的方法需要O(n)次比较。
而二分搜素搜的基本思想是将n个元素分成个数大致相同的两半,取arr[n/2]与x进行比较,如果x=arr[n/2],则找到x,算法终止。如果x<arr[n/2],则只要在数组arr的左半部继续搜索x。如果x>arr[n/2],则只要在数组arr的右半部继续搜索x。最坏情况下,也只需O(logn)次比较。
众所周知,二分查找是非常重要的查找方法,无论是笔试还是面试的过程中,都是如此,下面让我们一起来研究一下二分查找算法中的难点和考点。
1,溢出问题(迭代实现)
//代码1#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<stdlib.h>int bin_search(int arr[],int key,int sz){ int i=0;int left=0;<span style="color:#ff0000;">int right=sz-1</span>;while(<span style="color:#ff0000;">left<=right</span>){<span style="color:#ff0000;">int mid=(left+right)/2;</span> //如果left和right都很大,则mid将产生溢出,导致错误 if(key==arr[mid]){ return mid;}else if(key<arr[mid]){ <span style="color:#ff0000;">right=mid-1</span>;}else{ left=mid+1;}} <span style="color:#ff0000;"> return -1</span>;}int main(){int arr[]={1,2,3,4,5,6,7,8,9};int key=5;int sz=sizeof(arr)/sizeof(arr[0]);int ret=bin_search(arr,key,sz);if(ret==-1){ printf("没找到所查找元素\n");}else{ printf("所查找元素的下标为:%d\n",ret);}system("pause");return 0;}
注意:红色标注的都是最喜欢考到的地方
正如代码中注释的那样,
//如果left和right都很大,则mid将产生溢出,导致错误这样的话,我们就不得不想出一个办法解决溢出问题,可以联系一下日常的爬楼梯。
除了以上两种方法,还能不能有其他防止溢出的方法呢,
第一种最简单,但是存在风险,第二种就比较常用了,第三种一般想不到,所以建议学会理解第二种防止溢出的办法。
//如果left和right都很大,则mid将产生溢出,导致错误这样的话,我们就不得不想出一个办法解决溢出问题,可以联系一下日常的爬楼梯。
//代码2:#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<stdlib.h>int bin_search(int arr[],int key,int sz){ int i=0;int left=0;int right=sz-1;while(left<=right){int mid=(right-left)/2+left; //防止数据发生溢出 if(key==arr[mid]){ return mid;}else if(key<arr[mid]){ right=mid-1;}else{ left=mid+1;}} return -1;}int main(){int arr[]={1,2,3,4,5,6,7,8,9};int key=5;int sz=sizeof(arr)/sizeof(arr[0]);int ret=bin_search(arr,key,sz);if(ret==-1){ printf("没找到所查找元素\n");}else{ printf("所查找元素的下标为:%d\n",ret);}system("pause");return 0;}
除了以上两种方法,还能不能有其他防止溢出的方法呢,
//代码3:#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<stdlib.h>int bin_search(int arr[],int key,int sz){ int i=0;int left=0;int right=sz-1;while(left<=right){int mid=(left&right)+((left^right)>>1); //防止数据发生溢出 if(key==arr[mid]){ return mid;}else if(key<arr[mid]){ right=mid-1;}else{ left=mid+1;}} return -1;}int main(){int arr[]={1,2,3,4,5,6,7,8,9};int key=1;int sz=sizeof(arr)/sizeof(arr[0]);int ret=bin_search(arr,key,sz);if(ret==-1){ printf("没找到所查找元素\n");}else{ printf("所查找元素的下标为:%d\n",ret);}system("pause");return 0;}
第一种最简单,但是存在风险,第二种就比较常用了,第三种一般想不到,所以建议学会理解第二种防止溢出的办法。
2,区间问题
如果仔细观察,你就会发现上面几个代码用的都是前闭后闭区间,因为right是从sz-1开始取值的,那么如果是前闭后开区间,代码又会发生怎样的变化呢?让我们拭目以待。
<pre name="code" class="cpp">#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<stdlib.h>int bin_search(int arr[],int key,int sz){ int i=0;int left=0;<span style="color:#ff0000;">int right=sz;</span>while(<span style="color:#ff0000;">left<right</span>){int mid=(left&right)+((left^right)>>1); //防止数据发生溢出 if(key==arr[mid]){ return mid;}else if(key<arr[mid]){ <span style="color:#ff0000;"> right=mid;</span>}else{ left=mid+1;}} return -1;}int main(){int arr[]={1,2,3,4,5,6,7,8,9};int key=8;int sz=sizeof(arr)/sizeof(arr[0]);int ret=bin_search(arr,key,sz);if(ret==-1){ printf("没找到所查找元素\n");}else{ printf("所查找元素的下标为:%d\n",ret);}system("pause");return 0;}
注意:红色标注是改变的地方
3,递归实现
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<stdlib.h>int bin_search(int arr[],int left,int right,int key){while(left<right){ int mid=(left&right)+((left^right)>>1); //防止数据发生溢出if(key==arr[mid]){return mid;}else if(key<arr[mid]){return bin_search(arr,left,mid,key);}else{return bin_search(arr,mid+1,right,key);}}return -1;}int main(){int arr[]={1,2,3,4,5,6,7,8,9};int key=9;int sz=sizeof(arr)/sizeof(arr[0]);int ret=bin_search(arr,0,sz,key);if(ret==-1){ printf("没找到所查找元素\n");}else{ printf("所查找元素的下标为:%d\n",ret);}system("pause");return 0;}
1 0
- 二分查找的多种实现
- 二分查找的实现
- 二分查找的实现
- 二分查找的实现
- 二分查找的实现
- 二分查找的实现
- 二分查找的实现
- 二分查找的实现
- 二分查找的实现
- 二分查找的实现
- 二分查找的C++实现
- 二分查找的Java实现
- 二分查找算法的实现
- 二分查找的 C++ 实现
- 实现二分查找的算法
- Python实现的二分查找
- 二分查找的java实现
- js 二分查找的实现
- Struts2
- Eclipse 中常用的快捷键
- 文章标题
- ARM-Linux Gcc cross Compile Environment Set
- leetcode 33. Search in Rotated Sorted Array __java
- 二分查找的多种实现
- c的链表
- adams常用函数说明
- 字符串反转
- javafx的一些小技巧
- BZOJ斜率优化水题集
- UVALive3181-Fixing the Great Wall(区间dp)
- java中的值传递与引用传递
- windchill11 安装遇到的问题