二分查找算法

来源:互联网 发布:ubuntu修改grub启动项 编辑:程序博客网 时间:2024/05/16 12:53

1、思想

对于一个升序数组,给定一个有序(非降序)数组A,求任意一个i使得A[i]等于target,不存在则返回-1

2、算法示例


3、算法实现

(1)非递归算法

public static int binarySearch(int[] value,int key){int begin=0,end=value.length-1;while(begin<=end){int mid=(begin+end)/2;if(value[mid]==key)return mid;if(value[mid]>key)end=mid-1;else begin=mid+1;}return -1;}

(2)递归算法

public static int binarySearchRecurrence(int[] value,int begin,int end,int key){if(begin <= end){int mid = (begin+end)/2;if(value[mid] == key){return mid;} else if(value[mid] > key){return binarySearchRecurrence(value, begin, mid-1, key);} else{return binarySearchRecurrence(value, mid+1, end, key);}}return -1;}

(3)对于一个升序数组,给定一个有序(非降序)数组A,求最小的i使得A[i]等于target,不存在则返回-1

public static int binarySearchmix(int[] value,int key){int begin=0,end=value.length-1;while(begin<end){//如果最后剩下 begin,end(begin),并且两个值相同int mid=begin+(end-begin)/2;//mid为中间位置偏左if(value[mid]<key)begin=mid+1;else//value[mid]>=keyend=mid;}//begin=endif(value[end]==key)return end;elsereturn -1;}

(4)给定一个有序(非降序)数组A,可含有重复元素,求最大的i使得A[i]等于target,不存在则返回-1

public static int binarySearchmax(int[] value,int key){int begin=0,end=value.length-1;while(begin<end){//如果最后剩下 begin,end(begin),并且两个值相同。若mid偏左 怎么会出现死循环int mid=end-(end-begin)/2;//mid为中间位置偏右if(value[mid]<=key)begin=mid;elseend=mid-1;} if(value[end]==key)return end;elsereturn -1;}

(5)统计出现的次数

public static int binarySearchCount(int[] value, int key){// 找出key在value中最左边的位置int left = binarySearchmix(value, key);if(left == -1){return -1;}// 找出key在value中最右边出现的位置int right = binarySearchmax(value, key);return right-left;}

(6)循环升序数组,无重复元素

一个有序(升序)数组,没有重复元素,在某一个位置发生了旋转后,即递增数组右移。求target在变化后的数组中出现的位置,不存在则返回-1)。比如4、5、6、7、1、2、3

public static int binarySearchcircu(int[] value,int key){int begin=0,end=value.length-1;while(begin<=end){int mid=begin+(end-begin)/2;if(value[mid]==key)return mid;if(value[mid]>value[begin]){//begin~mid 升序if(key<value[mid]&&key>=value[begin])end=mid-1;elsebegin=mid+1;}else{//mid~end 升序if(key>value[mid]&&key<value[end])begin=mid+1;elseend=mid-1;}}return -1;}


(7)调用结果

/** * 二分查找 * @author zzj * */public class BinarySearch {public static void main(String[] args){int[] table={1,4,5,5,5,5,15,16,18,20};int key =5;System.out.println("原始数组为:"+Arrays.toString(table));System.out.println("查找的key为:"+key);// 1、非递归int index1=binarySearch(table,key);System.out.println("非递归找到一个退出,"+key+"下标为:"+index1);// 2、递归int index2 = binarySearchRecurrence(table, 0, 9, key);System.out.println("递归找到一个退出,"+key+"下标为:"+index2);// 3、出现位置最小的下标int indexMix=binarySearchmix(table,key);System.out.println(key+"下标最小的值:"+indexMix);// 4、出现位置最大的下标int indexMax=binarySearchmax(table,key);System.out.println(key+"小标最大的值:"+indexMax);// 5、统计出现的次数int count= binarySearchCount(table, key);System.out.println(key+"出现的次数:"+count);// 6、循环升序数组int[] circuTable = {4,5,6,7,1,2,3};int circuKey = 1;System.out.println("原始数组为:"+Arrays.toString(circuTable));System.out.println("查找的key为:"+circuKey);int indexCircu = binarySearchcircu(circuTable, 1);System.out.println("循环升序数据,"+key+"下标为"+indexCircu);}}

调用结果:

原始数组为:[1, 4, 5, 5, 5, 5, 15, 16, 18, 20]查找的key为:5非递归找到一个退出,5下标为:4递归找到一个退出,5下标为:45下标最小的值:25小标最大的值:55出现的次数:3原始数组为:[4, 5, 6, 7, 1, 2, 3]查找的key为:1循环升序数据,5下标为4


4、算法分析

时间复杂度:O(logn)