<?php
//基本查找算法
define('LEN',99999);
define('MAX',-99999);
class Node
{
public $data;//数据域
public $key; //关键之查找
}
$seqList = new SplFixedArray(LEN);
function Init(SplFixedArray $seqList)
{
for($i=0;$i<LEN;$i++){
$node = new Node();
$node->data = 'val'.$i;
$node->key = $i; //这里直接按关键之排好序
$seqList[$i] = $node;
}
}
Init($seqList);
//1.顺序查找
//平均查找长度O((n+1)/2)
function seqSearch(SplFixedArray $seqList,$key)
{
for($i=0;$i<LEN;$i++){
if($seqList[$i]->key == $key){
return $i;
}
}
return -1;
}
//test
$key = rand(1,99998);
$start = microtime(true);
$res = seqSearch($seqList, $key);
$end = microtime(true);
var_dump($res);
echo 'Time:',$end-$start,'---';
if($res!=-1){
echo $seqList[$res]->key,'=>',$seqList[$res]->data,'<br/>';
}
//2.二分查找
//需要按关键字排序,快排时间复杂度O(nlog2n)
//二分查找最坏的性能和平均相近都为 log2n
function binSearch(SplFixedArray $seqList,$key)
{
$low = 0;
$high = LEN-1;
while($low<=$high){
$mid = (int)(($low+$high)/2);
if($seqList[$mid]->key>$key){
$high = $mid-1;
}else if($seqList[$mid]->key<$key){
$low = $mid+1;
}else{
return $mid; //查找成功
}
}
return -1;//查找失败
}
//test
$start = microtime(true);
$res = binSearch($seqList, $key);
$end = microtime(true);
var_dump($res);
echo 'Time:',$end-$start,'---';
if($res!=-1){
echo $seqList[$res]->key,'=>',$seqList[$res]->data,'<br/>';
}
//3.分块查找
//当使用顺序查找是 分块查找的平均长度为:(假设分为b快,每块长度为s =>s = (n/b)向上取整 )
//(b+1)/2+(s+1)/2 = (s*s+2*s+n)/2*s =>当s为 根号 n是平均查找长度最短 :根号n +1
//也可以使用二分查找来确定块,因为索引是有序的,且必须是前一块的最大关键字必须小于后一块的最小关键字
//此算法是介于顺序查找和二分查找之间
//索引结构
class IndexNode
{
public $key; //记录当前快中最大的key数
public $link; //连接当前块的起始地址
}
function InitIndex(SplFixedArray $seqList)
{
$s = ceil(sqrt(LEN)); //每块的数
$b = $s; //块数
$indexList = new SplFixedArray($b);
for($i=0;$i<$s;$i++){
$max = MAX;
for($j=0;$j<$s;$j++){
if($i*$s+$j<LEN&&$max<$seqList[$i*$s+$j]->key){ // 避免越界,因为最后一块元素可能没有根号n个
$max = $seqList[$i*$s+$j]->key;
$flag= $j;
}
}
$idx = new IndexNode();
$idx->key = $max; //记录最大键值
$idx->link = $i*$s; //记录起始位置
$indexList[$i] = $idx;
}
return $indexList;
}
$indexList = InitIndex($seqList);
function IdxSearcch(SplFixedArray $seqList,SplFixedArray $idx,$key)
{
$low = 0;
$high = ceil(sqrt(LEN))-1;
$s = $high; //这里s记录每块的个数
while($low<=$high){
$mid = (int)(($low+$high)/2);
if($idx[$mid]->key<$key){
$low = $mid+1;
}else{
$high = $mid-1;
}
}
$i = (int)($idx[$high+1]->link); //这里对应的索引块必定为$high+1
while($i<LEN&&$i<$idx[$high+1]->link+$s-1&&$seqList[$i]->key!=$key){
$i++;
}
if($i<$idx[$high+1]->link+$s-1&&$i<LEN){ //最后一个块的元素可能会小于 $s
return $i; //查找成功
}
return -1; //查找失败
}
//test
$start = microtime(true);
$res = IdxSearcch($seqList, $indexList, $key);
$end = microtime(true);
var_dump($res);
echo 'Time:',$end-$start,'---';
if($res!=-1){
echo $seqList[$res]->key,'=>',$seqList[$res]->data,'<br/>';
}
?>
基本查找算法 PHP 实现 保存 顺序查找,二分查找 分块查找
最新推荐文章于 2024-04-19 19:44:24 发布