서문:
앞서 이진 검색을 소개했는데, 생각해보면 왜 반으로 해야 할까요? 4분의 1 이상으로 접는 것보다?
예를 들어 영어 사전에서 'apple'을 검색하면 사전을 펼칠 때 무의식적으로 앞 페이지로 넘어가나요, 아니면 뒷 페이지로 넘어가나요? "동물원"을 다시 확인하면 어떻게 확인하나요? 당연히 사전의 중간부터 찾아보기 시작하는 것이 아니라, 어떤 목적을 가지고 앞이나 뒤를 바라봅니다.
마찬가지로 예를 들어 0~10000의 값 범위에서 작은 것부터 큰 것까지 균등하게 분포된 100개의 요소가 있는 배열에서 5를 찾으려면 자연스럽게 작은 배열의 첨자를 먼저 고려하여 검색을 시작합니다. .
위의 분석은 사실 이진탐색을 개선한 보간탐색의 아이디어이다.
기본 아이디어:
검색 방법은 검색할 키워드 키를 조회 테이블의 최대 레코드와 최소 레코드의 키워드와 비교하는 것의 핵심입니다. 계산 공식:
$key - $arr[$low]
——————————-
$arr[$high] - $arr[$low]
코드:
<?php //插值查找(前提是数组必须是有序数组) 事件复杂度 O(logn) //但对于数组长度比较大,关键字分布又是比较均匀的来说,插值查找的效率比折半查找的效率高 $i = 0; //存储对比的次数 //@param 待查找数组 //@param 待搜索的数字 function insertsearch($arr,$num){ $count = count($arr); $lower = 0; $high = $count - 1; global $i; while($lower <= $high){ $i ++; //计数器 if($arr[$lower] == $num){ return $lower; } if($arr[$high] == $num){ return $high; } // 折半查找 : $middle = intval(($lower + $high) / 2); $middle = intval($lower + ($num - $arr[$lower]) / ($arr[$high] - $arr[$lower]) * ($high - $lower)); if($num < $arr[$middle]){ $high = $middle - 1; }else if($num > $arr[$middle]){ $lower = $middle + 1; }else{ return $middle; } } return -1; } $arr = array(0,1,16,24,35,47,59,62,73,88,99); $pos = insertsearch($arr,62); print($pos); echo "<br>"; echo $i;
요약:
시간 복잡도 관점에서 보면 O(logn)이지만 순서가 지정된 목록의 경우 더 길며 키워드 분포는 상대적으로 균일합니다. 조회 테이블의 경우 보간 검색 알고리즘의 평균 성능이 이진 검색의 성능보다 훨씬 좋습니다. 반대로 배열 내 분포가 {0, 1, 2, 2000, 2001,. . . 999998, 999999} 보간 검색을 사용하는 이러한 종류의 매우 고르지 않은 데이터는 그다지 적합한 선택이 아닐 수 있습니다.
위 내용은 PHP 순차 테이블 검색----보간 검색 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(m.sbmmt.com)를 참고해주세요!