您的位置:首页 > 理论基础 > 数据结构算法

数据结构——二分搜索

2017-03-22 23:41 309 查看

递归实现

/**
* 二分搜索(递归实现)
* @param A     待搜索数组
* @param num   搜索值
* @param left  区间左指针
* @param right 区间右指针
* @param mid   基准
*/
private static void search(int[] A, int num, int left, int right, int mid) {
if (A[mid] == num) { // 如果找到要找的数,记录其下标
res = mid;
}
if (left >= right)
return ;
if (A[mid] >= num) { // 出现在左边
right = mid - 1;
mid = left + (right-left)/2;
search(A, num, left, right, mid);
}
if (A[mid] < num) { // 出现在右边
left = mid + 1;
mid = left + (right-left)/2;
search(A, num, left, right, mid);
}
}


非递归实现

/**
* 二分搜索(非递归实现)
* @param A     带搜索数组
* @param n     数组长度
* @param num   搜索值
* @return
*/
private static int search2(int[] A, int n, int num) {
int left = 0;
int right = n - 1;
int res = -1;
while (left <= right) {
int mid = left + (right - left)/2;
if (A[mid] == num) {
res = mid;
right = mid - 1;
}
if (A[mid] >= num) { // 左区间
right = mid - 1;
} else {
left = mid + 1;
}
}
return res;
}

private static int search3(int[] arr, int n, int num) {
int left = 0;
int right = n-1;
while (left <= right) {
int mid = left + ((right-left)>>1);
if (arr[mid] > num) {
right = mid-1;
}else if (arr[mid] < num) {
left = mid+1;
}else {
return mid;
}
}
return -1;
}


简单应用:在有序数组中查找某数 num 的出现次数 m

给定数组 arr 和要找的数为 num。

首先确定 num 最左出现的下标位置,记为 indexL,再确定 num 在数组中最右出现的下标位置,记为 indexR。

比如 arr = {0,1,1,2,3,3,3,4}

当 num = 1 时,indexL = 1,indexR = 2,出现次数 m = indexR - indexL + 1;

当 num = 2 时,indexL = 3,indexR = 3,m = 1,因为 indexL == indexR;

当 num = 4 时,indexL = 7,indexR = 7;m = 1;

/**
* Created by zhengbinMac on 2017/4/11.
*/
public class Search {
public static void main(String[] args) {
int[] arr = {0, 1, 1, 2, 3, 3, 3, 4};
int m = search(arr, 3);
System.out.println(m);
}
private static int search(int[] arr, int num) {
int indexL = 0;
int indexR = 0;
int left = 0;
int right = arr.length - 1;
// 找到数组中为 num 的最左下标位置
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (arr[mid] > num) {
right = mid - 1;
}else if (arr[mid] < num) {
left = mid + 1;
}else {
right = mid - 1;
indexL = mid;
}
}
left = 0;
right = arr.length - 1;
// 找到数组中为 num 的最右下标位置
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (arr[mid] > num) {
right = mid - 1;
}else if (arr[mid] < num) {
left = mid + 1;
}else {
left = mid + 1;
indexR = mid;
}
}
if (indexR == indexL) {
return 1;
}else {
return indexR - indexL + 1;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: