二分查找(折半查找)的两种Java实现方式

一、简介

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

二、查找过程

首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

     用于二分查找的数组前提是排好序的,先将要查找元素与侍比较数组的中间元素比较,如果大于中间元素则将比较范围缩小到中间元素+1到末尾元素,如果小于中间元素则将范围缩小到开始元素到中间元素-1。以此规则不断比较直到找到侍查找元素为止,循环的停止条件为start<end表明在将所有元素查找了一遍之后仍末找到侍查找元素,结束循环。 

      优点:比较元素少,查找速度快,平均性能好。

      缺点:要求侍查找表为有序表。

三、图示说明(图片来源网络)

《二分查找(折半查找)的两种Java实现方式》

四、两种实现方式

时间复杂度:

最好情况下为O(1)

最坏情况下两种方式复杂度相同为:O(log2 N)

空间复杂度:

非递归方式,由于辅助空间是常数级别的所以,空间复杂度是O(1)。

递归方式:递归的次数和深度老师log2N,每次所需要的辅助空间都是常数级的:O(log2N)

1、非递归方式

public class BinarySearch {
	public static void main(String[] args) {
                //测试用例
		int[] arr = {2,4,5,6,8,9,12,14,23,34,46,57,68,69,78};
		int key = binarySearch(arr,11);
		System.out.println(key);
	}

	private static int binarySearch(int[] arr,int key) {
		int start = 0;
                //因为数组下标从0开始,所以结尾是arr.length-1;
		int end = arr.length-1;
		int middle = 0;
		while(start<=end) {
                        //每次没有找到时middle被重新赋值,并且用于之后的循环
			middle= (start+end)/2;
			//如果侍查找元素等于数组中间数,则直接返回数组下标
			if (key==arr[middle]) {
				return middle;
                         //如果侍查找元素大于数组中间数,则将范围缩小到后一半
			}else if (key>arr[middle]) {
				start = middle+1;
                        //如果侍查找元素小于数组中间数,则将范围缩小到前一半
			}else if(key<arr[middle]){
				end = middle-1;
			}
		}
		return -1;
	}
}

2、递归方式

private static int recursionBinarySearch(int[] arr,int key,int start,int end) {
		
		if (key<arr[start]||key>arr[end]||start>end) {
			return -1;
		}
		
		int middle = (start+end)/2;
		if (key>arr[middle]) {
			return recursionBinarySearch(arr, key, middle+1, end);
		}else if (key<arr[middle]) {
			return recursionBinarySearch(arr, key, start, middle-1);
		}else {
			return middle;
		}
	}

 

点赞