1. 程式人生 > >java資料結構之折半查詢

java資料結構之折半查詢

折半查詢,也稱二分法查詢、二分搜尋,是一種在有序陣列中查詢某一特定元素的搜尋演算法,這裡強調有序表明這種演算法的特定使用場景;

搜素過程為,從陣列中間元素開始,如果中間元素正好是要查詢的元素,則搜素過程結束;

如果某一特定元素大於或者小於中間元素,則在陣列大於或小於中間元素的那一半中查詢,而且跟開始一樣從中間元素開始比較。如果在某一步驟陣列已經為空,則表示找不到指定的元素。這種搜尋演算法每一次比較都使搜尋範圍縮小一半,相比順序查詢,其時間複雜度是O(logN);

折半查詢的精髓在於這個折半的程式程式碼的編寫,這裡將使用兩種方式進行折半查詢,第一張是按照上述解釋的意思,每次排除一般的資料,另一種方式是,考慮到查詢的過程的重複性,使用遞迴演算法進行查詢,下面上程式碼,

1、給定一個有序陣列,再給定一個特定的資料,如果這個資料存在於這個陣列中,返回資料對應的下標,否則返回-1,程式碼比較簡單,相信大家一看就懂;

public class TestSearch {
	
	public static void main(String[] args) {
		//定義一個數組
		int[] searchArr = {1,2,3,4,5,6,7,8,9,10};
		//給定要查詢的數
		int num = 5;
		//執行查詢
		int index = -1;
		for(int i=0;i<searchArr.length;i++){
			if(num == searchArr[i]){
				index = i;
			}
		}
		if(index == -1){
			System.out.println("沒有找到");
		}else{
			System.out.println("找到了這個數,在陣列中的下標是:" + index );
		}
	}
}

2、下面用折半查詢第一種方式來做

/**
	 * @param arr  給定陣列
	 * @param key  要查詢的值
	 * @return
	 */
	public static int doSearch(int[] arr,int key){
		//指定一個最小值
		int low = 0;
		//指定最大值
		int high = arr.length - 1;
		//判斷key和middle的關係
		while(low <= high){
			//初始化指定一箇中間值
			int middle = (low + high)/2;
			if(key == arr[middle]){
				return middle;
			}else if(key < arr[middle]){
				high = middle - 1;
			}else if(key > arr[middle]){
				low = middle + 1;
			}
		}
		return -1;
	}

然後再在main函式中呼叫,

public static void main(String[] args) {
		int[] array = {1,2,3,4,5,6,7,8,9,10};
		//給定要查詢的資料
		int key = 3;
		//執行查詢的流程,不使用遞迴
		int index = doSearch(array, key);
		//折半查詢,採用遞迴演算法
		//int index = bianarySearch(array,key);
		//輸出結果
		if(index == -1){
			System.out.println("要查詢的資料不存在");
		}else{
			System.out.println("資料所在的下標是:" + index);
		}
	}

執行,可以看到要查詢的結果是否在我們的陣列中,

下面採用遞迴的方式進行查詢,

/**
	 * 遞迴進行折半查詢資料
	 * @param arr
	 * @param key
	 * @return
	 */
	public static int bianarySearch(int[] arr,int key){
		int low = 0;	//從0開始
		int high = arr.length - 1;
		return doSearchForDiGui(arr,key,low,high);
	}
	
	/**
	 * 遞迴方式查詢
	 * @param arr	給定資料
	 * @param key	要查詢的資料
	 * @param low	最小下標
	 * @param high	最大下標
	 * @return
	 */
	public static int doSearchForDiGui(int[] arr,int key,int low,int high){
		if(low > high){
			return -1;
		}
		int middle = (low +high)/2;
		if(key == arr[middle]){
			return middle;
		}else if(key < arr[middle]){
			return doSearchForDiGui(arr,key,low,middle-1);
		}else{
			return doSearchForDiGui(arr,key,middle+1,high);
		}
	}

然後再在main函式中呼叫,

public static void main(String[] args) {
		int[] array = {1,2,3,4,5,6,7,8,9,10};
		//給定要查詢的資料
		int key = 3;
		//執行查詢的流程,不使用遞迴
		//int index = doSearch(array, key);
		//折半查詢,採用遞迴演算法
		int index = bianarySearch(array,key);
		//輸出結果
		if(index == -1){
			System.out.println("要查詢的資料不存在");
		}else{
			System.out.println("資料所在的下標是:" + index);
		}
	}

執行,可以看到要查詢的結果是否在我們的陣列中