二分查找法

条件:1.数组   2.有序(升序/降序)

一、最基本的二分查找

package twoFind

object test02 {
  def main(args: Array[String]): Unit = {
    var z = Array ( 1, 2, 3, 4, 5, 6, 7, 8, 9 )
    val y: Int = seach ( z, 7 )

    if (y == 1) {
      println ( "要查找的值不存在!" )
    }
  }

  def seach(array: Array[Int], target: Int): Int = {
    var low = 0 //下边界  数组的开始下标
    var high = array.length - 1 //上边界  数组的结尾下标
    var x = 1
    //判断条件  low<=high
    while (low <= high) {
      println ( "" + x + "次对比" )
      x += 1
      var mid = low + ( high - low ) / 2 //防止数值溢出也可以写(low+hight)/2
      if (target == array ( mid )) {
        println ( "找到了,在" + mid + "位置" )
        return mid
      } else if (target < array ( mid )) {
        println ( array ( mid ) + "" + target + "大,继续查找" )
        high = mid - 1

      } else {
        println ( array ( mid ) + "" + target + "小,继续查找" )
        low = mid + 1
      }
    }
    return -1
  }
}

注意:查找条件 :low<=high(下边界<=上边界)

2.为了防止溢出:mid=low+(high-mid)/2 (或者mid=(high+low)/2))

3.当array(mid)>target时 high=mid-1  当array(mid)<target时 low=mid+1

二、查找目标值区域在左边界(下边界)  查找与目标值相等的第一个位置/查找不小于目标值的第一个位置  

数组: x=Array(1,3,3,5,7,7,7,7,8,14,14)

目标值:7

返回值:4

package twoFind
object test03 {
  def main(args: Array[String]): Unit = {
    val x=Array(1,3,3,5,7,7,7,7,8,14,14)
val y:Int=seach(x,7)
 if (y == -1){
      println("没有此值!")
    }
}
def seach(array:Array[Int],target:Int): Int ={
    var low=0
    var high=array.length-1
    while (low<=high){
      var mid=low+(high-low)/2
      if(array(mid) >= target){
        high=mid-1
      }else{
        low=low+1
      }
    }
  //low<array.length可以不写
    if (low<array.length&&array(low)==target){
      println(low)
      return low
    }
    return -1
  }
}

三、查找的目标位置在右边界(上边界)  查找与目标值相等的最后位置/查找不小于目标值的第一个位置 

数组: x=Array(1,3,3,5,7,7,7,7,8,14,14)

目标值:7

返回值:7

package twoFind
object test03 {
def main(args: Array[String]): Unit = {
val x=Array(1,3,3,5,7,7,7,7,8,14,14)
val y:Int=seach(x,7)
if (y == -1){
println("没有此值!")
}else{
println(y)
}
}
def seach(array:Array[Int],target:Int): Int ={
var low=0
var high=array.length-1
while (low<=high){
var mid=low+(high-low)/2
if(array(mid)>target){
high=mid-1
}else{
low=mid+1
}
}

return if (low<array.length && array(low)==target)
-1
else low
}
}

四、查找的目标位置在右边界(上边界)  查找大于目标值的第一个位置/查找比目标值大,但是最接近目标值的数
当我们查找到的数值在右边界(上边界)时,那么在往右加一位,即为high+1,就是最后大于目标数。其实high+1也是退出循环low的值,因此此时刚好low=high+1,它大于high,刚好可以是的whil循环结束,我们只要判断low是否超出边界即可。

数组: x=Array(1,3,3,5,7,7,7,7,8,14,14)

目标值:7

返回值:8

package twoFind
object test03 {
  def main(args: Array[String]): Unit = {
    val x=Array(1,3,3,5,7,7,7,7,8,14,14)
    val y:Int=seach(x,7)
    if (y == -1){
      println("没有此值!")
    }
  }
  def seach(array:Array[Int],target:Int): Int ={
    var low=0
    var high=array.length-1
    while (low<=high){
      var mid=low+(high-low)/2
      if(array(mid) <= target){
        low=low+1
      }else{
        high=mid-1
      }
    }
    
    if (array(high)==target){
      println(high+1)
      return high+1
    }
    return -1
  }
}

五、查找的目标位置在左边界(下边界) 查找小于目标值的最后位置/查找比目标值小,但是最接近目标值的数

当我们查找到的数值在左边界(下边界)时,那么在往左退一位,即为low-1,就是最后小于目标数。其实low-1也是退出循环high的值,因此此时刚好high=low-1,它小于low,刚好可以是的whil循环结束,我们只要判断high是否超出边界即可。

数组: x=Array(1,3,3,5,7,7,7,7,8,14,14)

目标值:7

返回值:3

package twoFind
object test03 {
  def main(args: Array[String]): Unit = {
    val x=Array(1,3,3,5,7,7,7,7,8,14,14)
    val y:Int=seach(x,7)
    if (y == -1){
      println("没有此值!")
    }else{
      println(y)
    }
  }
  def seach(array:Array[Int],target:Int): Int ={
    var low=0
    var high=array.length-1
    while (low<=high){
      var mid=low+(high-low)/2
      if(array(mid) >= target){
        high=mid-1
      }else{
        low=mid+1
      }
    }

    return if (high < 0)
      -1
    else high
  }
}
原文地址:https://www.cnblogs.com/wangshuang123/p/11077844.html