經典資料查詢--二分查詢(簡單有序陣列的二分查詢)
阿新 • • 發佈:2019-01-09
引言
博主最近正在學習演算法相關知識,是一個初學者。從初學者的角度來進行了解什麼是二分查詢。
二分查詢就相當於猜數遊戲。我們小時候經常玩的猜數遊戲中所用的方法一樣。在這個遊戲裡,一個朋友會讓你猜他正想的一個1至100之間的數。當你猜了一個數後,他會告訴你三種選擇中的一個:你猜的比他想的大,或小,或猜中了。
所以為了能用最小的次數猜中,必須從50開始猜。如果他說你猜的太小,則推出哪個數在51至100之間,所以下一次猜75(50至100的一半)。但如果他說你猜的50有些大,則推出哪個數在1至49之間,下一次猜25。
每猜一次就會將可能的值劃分成兩部分。最後範圍會縮小到一個數字那麼大,就是答案。
以往都是從1開始,然後是2,3,4等等,一個個進行線性查詢。而在二分查詢中,每猜測一次都是將可能的值劃分成兩部分,因此猜測的次數大大減少。
以下就是線性和二次查詢:
以上二分查詢只適合有序陣列進行查詢,沒有考慮重複值等其他因素。便宜初學者瞭解什麼是二分查詢。/** * 有序陣列資料查詢 * @author whmAdmin * */ public class Search { private long[] a; // 查詢的陣列 private int nElems; // 陣列元素個數 /** * 線性查詢 時間複雜度O(N) * @param searchKey 查詢的數 * @return 存在true 不存在 false */ public boolean linearSearch(long searchKey) { int j; // 找到停止迴圈 for (j = 0; j < nElems; j++) { if(a[j] == searchKey) { break; } } // 判斷下座標 if(j == nElems) { return false; }else { return true; } } /** * 二分查詢有序陣列 時間複雜度O(logN) * @param searchKey * @return */ public int binarySearch(long searchKey) { // 下座標 int lowerBound = 0; // 上座標 int upperBound = nElems - 1; // 中間座標 int curIn; while(true) { // 獲取中間座標 curIn = (lowerBound + upperBound) /2; // 中間座標位置元素與查詢元素相等 if(a[curIn] == searchKey) { // 返回下座標 return curIn; // 上座標大於下座標 } else if(lowerBound > upperBound){ // 返回總位置數 return nElems; } else{ // 中間位置元素小於查詢元素 if(a[curIn] < searchKey) { // 下座標等於中間座標後一位座標上 lowerBound = curIn+1; }else { // 否則 上座標等於中間座標前一位座標上 upperBound = curIn -1; } } } } }