當我們用到數組的時候,通常會用到通過鍵來查找值,這種比較簡單,直接可以得出,但是當我們通過值來查找鍵時,就有些麻煩,有些語言提供了系統函數來實現這一功能,但是用別人的不如自己知道底層是怎麼實現的。這裏就介紹兩種方法來實現通過值來獲取鍵。以php語言爲例。
順序查找:數組可以是無序的,也可以是有序的,因爲順序查找是通過便利整個數組來確定鍵值。在php中可以通過foreach來進行遍歷。在這裏定義一個簡單的索引數組。用於遍歷尋找。
通過foreach進行遍歷。通過查找幫助文檔可以看到foreach的語言格式:
Foreach有兩種格式,第一種只得到值,第二種得到鍵和值。顯而易見,這裏我們使用第二種方式。
通過foreach逐個得到數組的值,得到值之後和傳入的值進行比較。如果相等,那麼這個值就是我們想找的那個值,而這個鍵值是$key,返回key,也就是值得下標。
代碼:
<?php
$arr = array(1,4,2,35,16,34,15);
function seek($arr,$value1){
foreach ($arr as $key => $value) {
if($value1 == $value){
return $key;
}
}
}
echo '15的索引值是:' . seek($arr,15);
?>
結果:
要知道,對於數組的下標,是從0開始計算的,所以15的在數組中是第七個數,下標是6;
二分查找:二分查找又稱爲折半查找,它比順序查找的速度要快很多,平穩性好,但是缺點是查詢的數組是一個有序的。
二分查找是把數組進行二分,先定義兩個邊界,一個是數組的開頭start 0,一個是數組的結束end count($arr) - 1;將中間位置(mid = start + end)/2的值和與查找的值進行比較,如果兩者相等,則查找成功,如果查找的值大於中間的值,則查找的值一定是在數組中間值得右邊,這是只需要把start = mid + 1;如果查找的值小於中間的值,則查找的值一定是在數組中間值得左邊,這時需要把end = mid - 1;循環查找,運行到最後,有兩種情況:
1、一種是查到要查的值
2、第二種是查找不到,並且start > end;
上面的話轉化成圖形也就是下面這個圖,但是當數組的mid是小數是,可以使用round()函數進行四捨五入。
能找到結果的示意圖:
Start > end的情況:
代碼實現:
<?php
$arr = array(1,2,4,6,7,12,15);
function binarySearch(&$arr,$value,$start,$end){
if($start > $end){
echo '沒有找到';
return;
}
$mid = round(($start + $end) / 2);
if($arr[$mid] == $value){
return $mid;
}else if($arr[$mid] > $value){
return erFen($arr,$value,$start,$mid - 1);
}else{
return erFen($arr,$value,$mid + 1,$end);
}
}
echo binarySearch($arr,13,0,count($arr) - 1);
這個二分查找用到遞歸。遞歸簡單來說就是自己調用自己,他有兩個條件,
1、必須有一些基準條件,它無需遞歸就能算出結果。
2、對於需要遞歸進行運算的,每一次遞歸調用都必須要向基準條件推進。
在上面的代碼中,
if($start > $end){
echo '沒有找到';
return;
}
if($arr[$mid] == $value){
return $mid;
}
都可以看作是基準條件。通過遞歸不斷的進行二分,從而得到結果。
總結:
- 順序查找查找效率低下,但是數組可以使無序的
- 二分查找雖然要求數組是有序的,但是查詢效率高。
- 至於使用哪種,就要看有什麼要求。