目录
1. 二分查找算法(折半查找)查找有序序列的多个相同数值
1.1 需求背景
我之前的这篇博文C++折半查找_二分查找算法简介与代码实现,只能查找有序序列的一个值,如果有序序列有多个相同的值时,则不能满足要求
1.2 需求
一个有序数组{1, 8, 10, 89, 1000, 1000, 1000, 1234},有多个相同的数值1000,请将所有1000都查找出来。请用Java实现
1.3 程序实现
import java.util.ArrayList;
import java.util.List;
public class BinSearch {
public static void main(String[] args) {
int[] seq = {1, 8, 10, 89, 1000, 1000, 1000, 1234};
// 进行二分查找
List<Integer> valueIndexList = binSearch(seq, 1000);
if (valueIndexList.size() == 0) {
System.out.println("未找到");
} else {
System.out.printf("找到的值的下标是: %s\n", valueIndexList);
}
}
public static List<Integer> binSearch(int[] seq, int findValue) {
int low = 0;
int high = seq.length - 1;
int mid;
int midValue;
// 如果low > high则表示未找到,返回空列表
while (low <= high) {
mid = (low + high) / 2;
midValue = seq[mid];
// 如果和二分值相同,则表示找到
if (findValue == midValue) {
List<Integer> valueIndexList = new ArrayList<Integer>();
valueIndexList.add(mid);
// 向找到的值左边,遍历查找相同值
int tmpIndex = mid - 1;
while (tmpIndex >= 0 && seq[tmpIndex] == findValue) {
valueIndexList.add(tmpIndex);
tmpIndex--;
}
// 向找到的值右边,遍历查找相同值
tmpIndex = mid + 1;
while (tmpIndex <= seq.length && seq[tmpIndex] == findValue) {
valueIndexList.add(tmpIndex);
tmpIndex++;
}
return valueIndexList;
// 如果比二分值大,则从后半部分查找
} else if (findValue > midValue) {
low = mid + 1;
} else {
// 如果比二分值小,则从后半部分查找
high = mid - 1;
}
}
return new ArrayList<Integer>();
}
}
运行程序,结果如下:
找到的值的下标是: [5, 4, 6]
2. 二分查找算法(非递归)的介绍和程序实现
2.1 二分查找算法(非递归)的介绍
二分查找法只适用于从有序的数列中进行查找。对于无序的数据需要将数列排序后再进行查找
二分查找法的运行时间为 O ( l o g 2 n ) O(log_2n) O(log2n) ,即查找到需要的目标位置最多只需要 l o g 2 n log_2n log2n步。假设从[0, 99]的队列(100个数,即n = 100)中寻到目标数30,则需要查找步数为 l o g 2 100 log_2100 log2100 , 即最多需要查找7次 ( 2 6 < 100 < 2 7 ) ( 2^6 < 100 < 2^7) (26<100<27)
2.2 二分查找算法(非递归)的程序实现
需求:对有序数组{1, 3, 8, 10, 11, 67, 100}, 用二分查找算法(非递归)对一个数进行查找
程序如下:
public class BinarySearchNoRecursion {
public static void main(String[] args) {
int[] array = {1, 3, 8, 10, 11, 67, 100};
int targetIndex = binarySearch(array, 100);
System.out.println("target index = " + targetIndex);
}
public static int binarySearch(int[] array, int target) {
int left = 0;
int right = array.length - 1;
// 继续查找的条件
while (left <= right) {
int mid = (left + right) / 2;
if (array[mid] == target) {
// 表示找到
return mid;
} else if (array[mid] > target) {
// 表示向左边查找
right = mid - 1;
} else {
// 表示向右边查找
left = mid + 1;
}
}
// 表示未找到
return -1;
}
}
运行程序,结果如下:
target index = 6