php查找之二分查找
阿新 • • 發佈:2018-03-21
return 返回 進行 最簡 pre 百度百科 表示 tar 針對
二分查找,往往是針對有序的數組進行查找,我們假設一個序列是數組有序,然後給定一個數字,查出它應該在這個數組中的排序位置
百度百科中講到
二分查找也稱折半查找(Binary Search),它是一種效率較高的查找方法。但是,折半查找要求線性表必須采用順序存儲結構,而且表中元素按關鍵字有序排列
折半查找這個名字一聽,你就知道是怎麽回事了。
我們舉個例子看看
1 3 5 7 9 10 是已經排好序的數組,如果現在要求查X,我們如何查出X放在哪個位置呢?
很顯然,我們可以取最中間的那個,然後假如找不到,就看中間的那個是大於X還是小於X 如果小於X,說明X應該在後半部分,如果是大於X,則說明在前半部分,那麽此時,再以當前中間節點為起始或者終止節點組成新數組,再次查找,如此往返,總能找到X的位置。
還是直接看代碼吧,最簡單的方式,遞歸實現,代碼如下:
<?php function binary_search($array,$target,$start,$end) { $middle_index = floor(($start+$end)/2); // 定位中間位置的索引 $middle_value = $array[$middle_index];//取得中間項的值 if($middle_value == $target) { return $middle_index; }else if($middle_value >$target) { if($start > $middle_index-1)//如果開始位置都比結束位置大了,表示肯定找不到了 { return false; } //中間項比要找的目標大 就去左邊找吧 $re = binary_search($array,$target,$start,$middle_index-1); }else { if($middle_index+1 > $end)//如果開始位置比結束位置大了 表示肯定找不到了 {return false; } //中間項比要找的目標小 就去右邊找吧; $re = binary_search($array,$target,$middle_index+1,$end); } return $re; } $array = array(1,3,5,7,9,10); $search = 9;//要找的數 $index = binary_search($array,$search,0,count($array)-1); var_dump($index);
截圖如下:
我們可以看到,使用遞歸方式的理解是非常簡單的,將大事化小,小事化了,如此往復來解決,分段分塊,逐步查找得到改元素,如果找不到 返回false。
那麽由於遞歸一直都是被認為是效率不高的,如何使用其他方式改寫一下這樣的查找方式呢?
我們可以用while循環實現叠代的方式來實現,代碼如下:
<?php function binary_search($array,$target,$start,$end) { $middle_index=floor(($start+$end)/2); while($start<=$end) { //說明還能繼續尋找 if($array[$middle_index]==$target) { //找到了 return $middle_index; }elseif($array[$middle_index]>$target) { //說明中間元素大於目標元素 在前半部分 $end=$middle_index-1;//終止位置從剛剛找到的中間位置的左邊那個位置結束 $middle_index=floor(($start+$end)/2);//重新計算中間位置 }else { //說明中間元素小於目標元素 在前半部分 $start=$middle_index+1;//起始位置中剛剛找到的中間位置的右邊那個位置開始 $middle_index=floor(($start+$end)/2);//重新計算中間位置 } } return false;//找不到 返回false } $array = array(1,3,5,7,9,10); $search = 9;//要找的數 $index = binary_search($array,$search,0,count($array)-1); var_dump($index);
截圖如下:
這樣的話,循環次數也少了,改寫了遞歸,降低了計算的復雜度。
php查找之二分查找