Scala、PHP、Golang 二分法查找

二分法查找是比较常见的查询算法。

对于一个有序序列,注意:是有序序列,找出其中某一个元素,通常的做法是序列中拿出一个一个的元素,每个元素和所需元素作比较,如果是想要的结果,就把元素的序号输出来。例如有序列:0, 3, 5, 7, 9, 11, 12, 13。我想要找7这个元素,我就取第一个元素0,和“11”比较,发现不是,然后取第二个“3”和“11”比较...直到取到第六个元素“11”,发现是想要的,就输出6。这样查询的时间复杂度很明显是N。

这样做显然不够完美,写程序是讲究运行效率的。以上面的序列“0, 3, 5, 7, 9, 11, 12, 13”为例,二分法的做法是:首先确定查找的“区间”,区间左端是“0”,区间右端是“13”,然后取这个区间中点作为和需要比较的对象比较,如果中点元素大于要查对象,就把中点作为下次查找的区间的左端(以从小到大的序列为例,如果序列是从大到小反之为右端),原来的右端还是右端;如果中点元素小于要查的对象,就把中点作为下次查找的区间的右端...然后继续这样比较,直到查到所查元素为止。这样查询的时间复杂度是log2N。可能很多人对于这个结果的所得表示很茫然,让我们来一起算一下。假设序列的长度是N,那么第一次查找后变为:N/2,第二次查找后:N/4...假设第x次 后找到所选数字:N/(2^x);这个时候序列的长度应该是大于或者等于1的;即2^x >= N ,由于算的是x的次数,可令 2^x = N ;得出:x = log2N 即时间复杂度为:log2N。如果这样不是很好理解,我们换一个思维想想:

  时间复杂度不就是循环的次数嘛,求时间复杂度实际上就是求循环了多少次呗~我们倒着推:假设现在已经取到所需的元素,那么现在的序列长度肯定是大于等于一,就令他为一,时间复杂度嘛,为的就是算最长需要的时间嘛,它现在乘以2就是上一次的长度,再乘以2就是上上此的长度,假设成了x次后变为了N,那么为: 2^x = N。循环次数x为log2N,即时间复杂度为:log2N。

以下分别是用Golang、PHP和Scala写的二分法查找:

Golang:

 

 
//输出-1代表没有此数字
func binarySearch(arry [8]int, val int) int {
   left := 0
   right := len(arry) - 1
   for left < right {
      var mid int = (right-left)/2 + left
      if val < arry[mid] {
         right = mid
      } else if left > arry[mid] {
         val = mid
      } else {
         return mid + 1
      }
   }
   return -1
}

 

 

 

PHP:

 

function binary_search(array $array, $val){
    $left = 0;
    $right = count($array)-1;
    while($left < $right){
        $mid = floor(($right - $left)/2) + $left;
        if($val > $array[$mid]){
            $right = $mid;
        }
        else if ($val < $array[$mid]){
            $left =$mid;
        }
        else{
            return $mid + 1;
        }
    }
    return false;
}

 

Scala:

 

 

def binarySearch(arry:Array[Int], needed:Int):Int={
  var left = 0
  var right = arry.length -1
  while(left < right) {
    val mid:Int = (right - left)/2 + left
    needed   match {
      case _ if needed > arry.apply(mid) => left = mid
      case _ if needed < arry.apply(mid) => right = mid
      case _ if needed == arry.apply(mid) => return mid + 1
    }
  }
  return -1
}

 

 

 

更多精彩内容,请关注我的个人公众账号 互联网技术窝

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜刚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值