查詢 二分查詢

2022-07-04 16:03:14 字數 3481 閱讀 9399

二分查詢也叫做折半查詢,查詢的物件是已經排好序的序列(一般預設為公升序)。

讓我們來看看原理:顧名思義,就是先將中間數和目標key比較,如果相等則返回其索引,否則把序列分成兩半,根據大小判斷所查詢的key在哪一半中,對這一半序列再重複上述步驟,直到找到目標key或查詢完序列。

被查詢的序列arr中無重複的元素,在此序列中查詢目標數target。

被查詢的序列示例:int arr1 = 。

public

static

int binarysearch(int arr, int

target)

// 確定別查詢的區間

int left = 0;

int right = arr.length - 1;

// 開始查詢【left,right】區間

while (left <=right)

else

if (arr[mid] >target)

else

if (arr[mid] }

// 如果未查找到,則返回-1

return -1;

}

第一步,初始化原序列,left指向索引為0的位置,即此區間的第乙個元素,right指向索引為arr.length-1的位置,即此區間最後乙個元素,也就是說這個區間是閉區間,[left,right]區間內的元素都是被查的元素。

第二步,找到中間元素的索引mid,判斷中間元數和目標數target的值是否相等:

第三步,當查詢到

left==right時,是最後乙個區間,即[left,left],此區間只有乙個元素,即下標為left的元素。如果此元素是目標數則查詢成功,返回其索引;如果不是,會重新確定left或right的值,使得left>right,查詢完畢退出迴圈,返回-1。

被查詢的序列arr中有重複的元素,在此序列中查詢目標數target。

被查詢的序列示例:int arr1 = 。

顧名思義,就是當序列中被查詢的數有多個時,找到最左邊的那個數的位置,然後返回其索引。當然,如果被查詢的數只有乙個,找到並返回其索引就好了,否則返回-1。

public

static

int binarysearch1(int arr, int

target)

int left = 0;

int right = arr.length; //

右側未閉合

while (left < right)

else

if (arr[mid] < target)

else

if (arr[mid] > target)

}if (left == arr.length)

return arr[left] == target ? left : -1;

}

大框架並沒有發生變化,改變的地方需要說一下:

首先,while的條件變了, left <= righ 變成了 left < right ,當left == right時退出迴圈,為什麼要變呢?因為我們這次所查詢的區間是左閉右開的,[left,right),當left增長到left == right時,所查詢的區間已查詢完畢,這時我們就要退出迴圈了。為什麼要這樣設計?此中妙處,請往下看。

if (left == arr.length)  這段**是幹啥的?這是當我們要查詢的數大於此序列的所有數時,left會一直增加到left == right,而此時的right並未改變,就是arr.length。這段**是為了處理這這種情況。

當中間數不是target時,調整下次要查詢的區間的範圍,大家應該可以理解,因為這是左閉右開的區間。

最後的 return arr[left] == target ? left : -1; 是為了應對target小於所有數時的情況和是否找到target時的情況。

與上面的相反,就是當序列中被查詢的數有多個時,找到最右邊的那個數的位置,然後返回其索引。當然,如果被查詢的數只有乙個,找到並返回其索引就好了,否則返回-1。

public

static

int binarysearch2(int arr, int

target)

int left = 0;

int right =arr.length;

while (left else

if (arr[mid] else

if (arr[mid] >target)

}if (left == 0)

return arr[left-1] == target ? (left-1) : -1;

}

當我們查詢左邊界的時候,我們是用right指標來鎖定左側邊界的;同理,當我們查詢右邊界的時候,我們用left來鎖定右邊界,但有一點小區別,因為查詢區間是左閉右開的,left指向的元素在查詢範圍內,因此我們用left的前乙個元素來鎖定右邊界。

這就是為什麼當中間元素等於target時,我們要 left = mid+1; 呢,left的前乙個元素最終會鎖定的右邊界,這也就對應了後面的return語句中為什麼是left - 1,因為left - 1指向的最右邊的target元素。

if (left == 0)  這段**是為了應對當target小於所有元素時的情況,因為後面有left-1,沒有這條語句的話會造成索引越界的情況。

二分查詢有乙個實現框架:

public

static

int binarysearch(int arr, int

target)

int left = 0;

int right = --------;

while (--------)

else

if (arr[mid] >target)

else

if (arr[mid] }

return --------;

}

當我們實現時根據題目的具體要求,來調整框架中所填部分的值。

一般的二分查詢最為簡單;當有重複數字時,查詢相對複雜一些,本文中只提到了查詢左右邊界的情況,但平常我們還會遇到一些變種的二分查詢情況,比如:查詢最後乙個等於或者小於key的元素、查詢最後乙個小於key的元素、查詢第乙個等於或者大於key的元素、查詢第乙個大於key的元素等。雖然變化很多,但萬變不離其宗!讀者只要理解查詢的原理和每一步的過程,將其融會貫通,便可攻無不克。

迭代二分查詢二分查詢

在寫這篇文章之前,已經寫過了幾篇關於改迭代二分查詢主題的文章,想要了解的朋友可以去翻一下之前的文章 bentley在他的著作 writing correct programs 中寫道,90 的計算機專家不能在2小時內寫出完整確正的二分搜尋演算法。難怪有人說,二分查詢道理單簡,甚至小學生都能明確。不過...

查詢 二分查詢

二分查詢也稱折半查詢 binary search 它是一種效率較高的查詢方法。但是,折半查詢要求線性表必須採用順序儲存結構,而且表中元素 按關鍵字有序排列 首先,假設表中元素是按 公升序排列 將表中間位置記錄的 關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功 否則利用中間位置 記錄將表分成前 後兩...

查詢 二分查詢

參考 原始碼 目錄 順序查詢 二分查詢 插值查詢 斐波那契查詢 分塊查詢 雜湊查詢 二叉樹查詢 紅黑樹查詢 演算法簡介 二分查詢 binary search 是一種在有序陣列中查詢某一特定元素的查詢演算法。查詢過程從陣列的中間元素開始,如果中間元素正好是要查詢的元素,則查詢過程結束 如果某一特定元素...