詳解二分查詢
阿新 • • 發佈:2021-05-03
二分查詢
引言
如何在一組遞增數列中查詢一個數,之前我們已經學習了順序查詢,就是按順序一個個查詢,但是當我們查詢一個很大的數的時候,例如231(大約21億)這時按順序查詢就會很繁瑣,需要搜尋231次。有沒有一種查詢方式既快捷又簡單呢?答案是有的,例如二分查詢。二分查詢又稱折半查詢,每一次查詢都會排除一半的選項,這樣大大減少了運算量。
具體思路
首先確定這組資料中間位置的數,把它和我們要找的數進行比較,如果相同那麼這個數就找到了,如果不同就比較這兩個數。若中間數大於要找的數就排除中間數右邊的資料,並把所找的中間數當做末位,取它和首位的中間數與要找的數進行比較。若中間數小於要找的數就排除中間數左邊的資料,並把所找的中間數當做首位,取它和末位的中間數與要找的數進行比較。重複上述操作直到找到為止。
程式碼實現
#include<stdio.h>
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int k = 0;
scanf("%d", &k);
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = sz - 1;
int mid = 0;
while (left <= right)
{
mid = (left + right) / 2;
if (arr[mid] > k)
{
right = mid - 1;
}
else if (arr[mid] < k)
{
left = mid + 1;
}
else
{
printf("找到了,arr[%d]=%d\n", mid,k);
break;
}
}
if (left>right)
{
printf("陣列中沒有這個數\n");
}
return 0;
}
程式碼逐句分析
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
建立一個遞增陣列
int k = 0;
scanf("%d", &k);
輸入要查詢的數
int sz = sizeof(arr) / sizeof(arr[0]);
計算陣列中元素個數`
int left = 0;
int right = sz - 1;
確定陣列的首位和末位
while (left <= right)
確定迴圈條件,當滿足左下標小於等於右下標時進入迴圈。
mid = (left + right) / 2;
找出中間數
while (left <= right)
{
mid = (left + right) / 2;
if (arr[mid] > k)
{
right = mid - 1;
}
else if (arr[mid] < k)
{
left = mid + 1;
}
else
{
printf("找到了,arr[%d]=%d\n", mid,k);
break;
}
}
對應上文二分查詢的具體思路
if (left>right)
{
printf("陣列中沒有這個數\n");
}
左下標大於右下標意味著陣列中沒有要找的數。
執行結果演示
分析與總結
二分查詢可以很快得在遞增數列中找到我們要找的數,但是它有很大的侷限性。
上文演示了二分查詢應用於遞增數列,不難看出二分查詢還可以應用與遞減數列,這個留給大家去思考。