JAVA代碼實現二分查找和插值查找

二分查找

二分查找,顧名思義就是折半查找。前提是數組必須是有序的。每次將查找的數和數組的中間值進行比較,如果要查找的數比中間值小就左遞歸繼續查找,如果要查找的數比中間值大,就右遞歸繼續查找,如果要查找的數存在,最終就是反覆遞歸後的中間值。

package com.search.BinarySerach;

import java.util.ArrayList;
import java.util.List;

public class BinarySearchDemo2 {

	public static void main(String[] args) {
		int[] arr = { 1, 3, 5, 7, 7, 7, 7, 9, 11, 13, 15 };
		List<Integer> binarySearch = binarySearch(arr, 0, arr.length - 1, 7);
		System.out.println("7的下標爲:" + binarySearch.toString());

	}

	/**
	 * 二分查找
	 * 
	 * @param arr     原數組
	 * @param left    每次查找的左邊
	 * @param right   每次查找的右邊
	 * @param findVal 要查找的值
	 * @return
	 */
	public static List<Integer> binarySearch(int[] arr, int left, int right, int findVal) {
		if (left > right) {
			return new ArrayList<Integer>();
		}
		// 1.先得到中間值和下標
		int mid = (left + right) / 2;
		int midVal = arr[mid];
		// 2.中間值和要查找的值進行比較
		if (midVal > findVal) {// 如果中間值大於要查找的值,那就向左遞歸查找
			return binarySearch(arr, left, mid - 1, findVal);
		} else if (midVal < findVal) {// 如果中間值小於要查找的值,那就向右遞歸查找
			return binarySearch(arr, mid + 1, right, findVal);
		} else {// 當中間值等於查找的值時,說明找到了
				// 可能要查找的值有多個,定義一個集合存放要查找的值的所有下標
			List<Integer> list = new ArrayList<Integer>();
			// 先向左掃描
			int temp = mid - 1;
			while (temp >= 0 && arr[temp] == midVal) {
				list.add(temp);
				temp--;
			}
			// 左邊掃描完畢後,將中間值的下標存放到集合中
			list.add(mid);
			// 再向右掃描
			temp = mid + 1;
			while (temp <= arr.length - 1 && arr[temp] == midVal) {
				list.add(temp);
				temp++;
			}
			return list;
		}

	}

}

插值查找

插值查找類似於二分查找,就是將查找方式換了。二分查找是mid=(left+right)/2這種折半的方式,而插值查找是根據要查找的數定義自適應的劃分線:mid = left + (left + right) * (findVal - arr[left]) / (arr[right] - arr[left])。其他步驟和二分查找一樣。
注意:
1.對於數據量較大,數字分佈比較均勻的查找表來說,插值查找速度較快;
2.關鍵字分佈不均勻的情況下,該方法不一定比折半查找要好。

package com.search.insertSearch;

import java.util.ArrayList;
import java.util.List;

public class InsertSearchDemo2 {

	public static void main(String[] args) {
		int[] arr = { 1, 3, 5, 7, 7, 7, 7, 9, 11, 13, 15 };
		List<Integer> binarySearch = insertSearch(arr, 0, arr.length - 1, 7);
		System.out.println("7的下標爲:" + binarySearch.toString());

	}

	public static List<Integer> insertSearch(int[] arr, int left, int right, int findVal) {
		if (left > right) {
			return new ArrayList<Integer>();
		}
		// 先得到劃分線的值和下標
		int mid = left + (left + right) * (findVal - arr[left]) / (arr[right] - arr[left]);
		int midVal = arr[mid];
		// 比較劃分線處的值和要查找的值
		if (findVal < midVal) {
			return insertSearch(arr, left, mid - 1, findVal);
		} else if (findVal > midVal) {
			return insertSearch(arr, mid + 1, right, findVal);
		} else {
			List<Integer> list = new ArrayList<Integer>();
			// 先向左掃描
			int temp = mid - 1;
			while (temp >= 0 && arr[temp] == midVal) {
				list.add(temp);
				temp--;
			}
			// 將劃分線的值放進去
			list.add(mid);
			// 再向右掃描
			temp = mid + 1;
			while (temp <= arr.length - 1 && arr[temp] == midVal) {
				list.add(temp);
				temp++;
			}
			return list;
		}
	}

}

如有錯誤,還望指出,我將及時改正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章