基本查找算法 PHP 实现 保存 顺序查找,二分查找 分块查找

来源:互联网 发布:sql select null as 编辑:程序博客网 时间:2024/05/20 04:29
<?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)//二分查找最坏的性能和平均相近都为 log2nfunction 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+1while($i<LEN&&$i<$idx[$high+1]->link+$s-1&&$seqList[$i]->key!=$key){$i++;}if($i<$idx[$high+1]->link+$s-1&&$i<LEN){ //最后一个块的元素可能会小于 $sreturn $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/>';}?>

0 0
原创粉丝点击