基本介绍
1.二分查找只适用于从有序的数列中进行查找(比如数字和字母),将数列排序后再进行查找。
2.二分查找法的运行时间为对数时间O(log2n),即查找到需要的目标位置最多只需log2n步,假设从[0,99]的队列中寻找目标数30,则需要查找步数为log2(100),即最多需要7次(2^6<100<2^7)。
代码案例
- packagecom.xie.algorithm;
- publicclassBinarySearchNoRecur{
- publicstaticvoidmain(String[]args){
- int[]arr={1,3,8,10,11,67,100};
- intindex=binarySearch(arr,1);
- System.out.println("index="+index);
- }
- /**
- *二分查找非递归实现
- *
- *@paramarr待查找的数组,arr是升序排列
- *@paramtarget需要查找的数
- *@return返回对应的下标,-1表示没有找到
- */
- publicstaticintbinarySearch(int[]arr,inttarget){
- intleft=0;
- intright=arr.length-1;
- while(left<=right){
- intmid=(left+right)/2;
- if(arr[mid]==target){
- returnmid;
- }elseif(arr[mid]>target){
- //需要向左边查找
- right=mid-1;
- }else{
- //需要向右边查找;
- left=mid+1;
- }
- }
- return-1;
- }
- }
基本介绍
1.插值查找算法类似于二分查找,不同的是插值查找每次从自适应的mid处开始查找。
2.二分查找中求mid索引的公式转成插值查找mid索引公式,low表示左边的索引,high表示右边的索引,key表示要查找的值
代码案例
- packagecom.xie.search;
- importjava.util.ArrayList;
- importjava.util.List;
- publicclassInsertValueSearch{
- staticintcount=0;
- publicstaticvoidmain(String[]args){
- int[]arr=newint[102];
- arr[0]=1;
- arr[1]=1;
- for(inti=2;i<102;i++){
- arr[i]=i;
- }
- List<Integer>indexList=insertValueSearch(arr,0,arr.length-1,1);
- System.out.println("indexList="+indexList);
- System.out.println("查找次数:"+count);
- /*
- indexList=[1,0]
- 查找次数:1
- */
- }
- /**
- *插值查找,返回索引集合
- *
- *@paramarr数组
- *@paramleft左边索引
- *@paramright右边索引
- *@paramfindValue要查找的值
- *@return找到就返回所有索引的集合,没有就返回空
- */
- publicstaticList<Integer>insertValueSearch(int[]arr,intleft,intright,intfindValue){
- count++;
- List<Integer>indexList=newArrayList<Integer>();
- //注意:findValue<arr[0]||findValue>arr[arr.length-1]这个必须要,否则mid可能越界
- if(left>right||findValue<arr[0]||findValue>arr[arr.length-1]){
- returnnewArrayList<Integer>();
- }
- intmid=left+(right–left)*(findValue-arr[left])/(arr[right]-arr[left]);
- intmidValue=arr[mid];
- if(findValue>midValue){
- returninsertValueSearch(arr,mid+1,right,findValue);
- }elseif(findValue<midValue){
- returninsertValueSearch(arr,left,mid-1,findValue);
- }else{
- //如果找到了,再向左扫描,将满足条件的加入indexList
- inttemp=mid-1;
- while(true){
- if(temp<0||arr[temp]!=findValue){
- break;
- }
- indexList.add(temp);
- temp–;
- }
- //再向右扫描,将满足条件的加入indexList
- temp=mid+1;
- while(true){
- if(temp>right||arr[temp]!=findValue){
- break;
- }
- indexList.add(temp);
- temp++;
- }
- indexList.add(mid);
- returnindexList;
- }
- }
- }
注意事项
- 对于数据量大,关键字分布比较均匀的查找表来说,采用插值查找,速度较快。
- 关键字分布不均匀的情况下,该方法不一定比二分法要好。
原文地址:https://www.toutiao.com/i6939142586317799968/