二分查找
二分查找,又叫做折半查找, 它是有序表的一种查找方式。
折半查找的效率比顺序查找高,但折半查找只适用于有序表,且限于顺序存储结构(对线性链表无法有效地进行折半查找)。
一、二分查找
算法实现
/** * 二分查找(最简单,无重复元素) */ public class BinarySearch { public static int binarySearch(int[] array, int value) { int low = 0; int high = array.length - 1; while (low <= high) { //int mid = (low + high) / 2;// 枢纽 //【这种写法更好,可以防止溢出】 int mid = low + (high - low) / 2; if (array[mid] > value)// 否则,在低位继续查找 high = mid - 1; else if (array[mid] < value)// 否则,在高位继续查找 low = mid + 1; else {// 找到了,返回所在位置 return mid; } } // 没找到 return -1; } public static void main(String[] args) { int[] array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int target = 5;// 要查找的值 int i = binarySearch(array, target); if (i > 0) { System.out.println("要找的值target=" + target + ",位于数组的下标索引:" + i); } else { System.out.println("不存在该值"); } } }
时间复杂度
三、带重复值的二分查找
如果带查找的有序表中有重复元素,则前面的实现代码要适当变一下了。我们的查找也要变成查找有序表中首次出现的某个元素。
/** * 二分查找(带有重复元素):在含有重复元素的顺序表中查找指定的元素首次出现的位置*/ public class BinarySearchWithRepeat { public static int BinarySearchWithRepeat(int[] array, int value) { int low = 0; int high = array.length - 1; while (low <= high) { int mid = (low + high) / 2;// 枢纽if (array[mid] > value)// 否则,在低位继续查找 high = mid - 1; else if (array[mid] < value)// 否则,在高位继续查找 low = mid + 1; else {// 找到了等值,但不一定是首次出现 if (mid == 0) {//当前就是首位,自然是首次出现 return mid; } if (array[mid - 1] != value) {//前一个值不等于当前值,说明当前值是首次出现 return mid; } else {//说明前面还有重复值,继续查找 high = mid - 1; } //return mid; } } // 没找到 return -1; } public static void main(String[] args) { int[] array = {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10}; int target = 5;// 要查找的值 int i = BinarySearchWithRepeat(array, target); if (i > 0) { System.out.println("要找的值target=" + target + ",首次出现位置:位于数组的下标索引:" + i); } else { System.out.println("不存在该值"); } } }
不积跬步,无以至千里。不积小流,无以成江海!