PHP之数据结构与算法实现

二分查找

//二分查找
$data = array(4,6,7,8,14,55,67,145,218,237,284);
function binarySearch($data, $num){
   
    $count = count($data);
    $high = $count - 1;
    $low = 0;
    while ($low <= $high){
   
        $mid = floor(($high + $low) / 2);
        //$mid = floor($low + ($num - $data[$low]) / ($data[$high] - $data[$low]) * ($high - $low));//插值查找
        if($num == $data[$mid]){
   
            return $mid;
        }elseif ($num > $data[$mid]){
   
            $low = $mid + 1;
        }else{
   
            $high = $mid -1;
        }
    }
    return false;
}
$res = binarySearch($data, 4);
var_dump($res); //1

插值查找(二分查找优化)
首先考虑一个新问题,为什么一定要是折半,而不是折四分之一或者折更多呢?
打个比方,在英文字典里面查“apple”,你下意识翻开字典是翻前面的书页还是后面的书页呢?如果再让你查“zoo”,你又怎么查?很显然,这里你绝对不会是从中间开始查起,而是有一定目的的往前或往后翻。
同样的,比如要在取值范围1 ~ 10000 之间 100 个元素从小到大均匀分布的数组中查找5, 我们自然会考虑从数组下标较小的开始查找。
经过以上分析,折半查找这种查找方式,还是有改进空间的,并不一定是折半的!
mid = (low+high)/ 2, 即 mid = low + 1/2 * (high - low);
改进为下面的计算机方案(不知道具体过程):mid = low + (key - a[low]) / (a[high] - a[low]) * (high - low),也就是将上述的比例参数1/2改进了,根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字key,这样也就间接地减少了比较次数。

分析:从时间复杂度上来看,它也是o(n),但是对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。反之,数组中如果分布非常不均匀,那么差值查找未必是很合适的选择。

二叉搜索树

<?php
class node{
   
	public $value;
	public $left;
	public $right;
	public $parent;

	public function __construct($data){
   
		$this->value = $data;
	}
}

class searchtree{
   
	public $root = null;
	public $size = 0;
	public $depth = 0;

	public function __construct($value){
   
		$this->root = new node($value);
		$this->size++;
		$this->depth++;
	}

	public function addnode($array){
   
		foreach ($array as $key=> $value) {
   
			$current = $this->root;
			$parent = null;
			$currentdepth = 1;

			while($current !== null){
   
				$parent = $current;
				if($current->value == $value){
   
					continue 2;
				}
				elseif($current->value > $value){
   
					$current = $current->left;
				}else{
   
					$current = $current->right;
				}
				$currentdepth++;
			}

			$node = new node($value);
			$node->parent = $parent;
			if($parent->value > $value){
   
				$parent->left = $node;
			}else{
   
				$parent-
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值