1. 程式人生 > 實用技巧 >演算法(Java實現)—— 二分搜尋演算法

演算法(Java實現)—— 二分搜尋演算法

二分搜尋演算法

有序數列才可用二分查詢演算法

思路分析

思路分析

  1. 首先確定該陣列的中間下標mid = (left + right)/ 2

  2. 然後讓需要查詢的數findVal和arr【mid】比較

    • findVal > arr[mid],向右查詢

    • findVal < arr[mid],向右查詢

    • findVal == arr[mid],找到,返回

  3. 結束遞迴的條件

    • 找到就結束

    • 遞迴完整個陣列,未找到,結束遞迴,left > right

二分查詢遞迴演算法

基本寫法

public static int binarySearch(int[] arr,int left,int right,int findVal){
if (left > right){
return -1;
}
//確定中間陣列的下標
int mid = (left + right)/2;
int midVal = arr[mid];

//與中間陣列比較
if (findVal > midVal){//向右查詢
return binarySearch(arr,mid+1,right,findVal);
}else if (findVal < midVal){
return binarySearch(arr,left,mid-1,findVal);
}else {
return mid;
}
}

新需求

當一個數組中有多個相同的數值是 ,將所有數值都查到

程式碼實現

package com.why.search;

import com.sun.jdi.PathSearchingVirtualMachine;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.logging.Level;

/**
* @Description TODO 當一個數組中有多個相同的數值是 ,將所有數值都查到,使用二分查詢
* @Author why
* @Date 2020/11/1 16:35
* Version 1.0
**/
public class NewBinarySearch {
public static void main(String[] args) {
int[] arr = {1,8,8,10,10,10,10,11};
List res = newBinarySearch(arr, 0, arr.length - 1, 8);
if (!res.isEmpty()){
System.out.println(res);
}else {
System.out.println("未找到");
}
}

/**
* 二分查詢查詢多條資料
*
* 思路:
* 找到mid值時,不要馬上返回
* 向mid 索引值的左邊掃描將所有滿足查詢值的元素下標加入到集合
* 向右掃描將所有滿足查詢值的元素下標加入到集合
* @param arr
* @param left
* @param right
* @param findVal
* @return
*/
public static List<Integer> newBinarySearch(int[] arr, int left, int right, int findVal){

if (left > right){
return new ArrayList<Integer>();
}
int mid = (left + right) / 2;
int midVal = arr[mid];


if (findVal > midVal){
return newBinarySearch(arr,mid + 1,right,findVal);
}else if (findVal < midVal){
return newBinarySearch(arr,left,mid - 1,findVal);
}else {
List<Integer> resIndexList = new ArrayList<>();
//向左邊掃描
int temp = mid - 1;
while (true){
if (temp < 0 || arr[temp] != findVal){
break;
}
resIndexList.add(temp);
temp -= 1;
}
//中間值
resIndexList.add(mid);
//向右掃描
temp = mid + 1;
while (true){
if (temp > arr.length || arr[temp] != findVal){
break;
}
resIndexList.add(temp);
temp += 1;
}
return resIndexList;
}
}
}

二分查詢非遞迴演算法

需求

陣列{1,3,8,10,11,67,100},程式設計實現二分查詢,以非遞迴形式完成

程式碼實現

package whyAlgorithm.binaryseaech;

import jdk.swing.interop.LightweightFrameWrapper;

/**
* @Description TODO 二分查詢非遞迴形式
* @Author why
* @Date 2020/12/9 19:53
* Version 1.0
**/
public class BinarySearchNoRecursion {
public static void main(String[] args) {
int[] arr = {1,3,8,10,11,67,100};
int target = binarySearch(arr,10);
System.out.println("下標:" + target);
System.out.println(arr[target]);
}

/**
* 二分查詢非遞迴演算法
* @param arr 陣列,升序排列
* @param target 需要查詢的演算法
* @return 返回陣列下標
*/
public static int binarySearch(int[] arr,int target){
int left = 0;
int right = arr.length - 1;
while (left <= right){//查詢
int mid = (left + right)/2;
if (arr[mid] == target){//找到中間數
return mid;
}else if (arr[mid] > target){//大於向左查詢
right = mid - 1;
}else {//小於向右查詢
left = mid + 1;
}
}
return -1;
}
}