简单的几种查找算法

查找算法
  • 顺序查找
  • 二分查找
  • 插值查找
  • 扩展
顺序查找
  • 顺序查找(Sequential Search) 又叫线性查找,是按照序列原有的顺序 对数组 进行 遍历比较 查询的基本查询方法

  • 查找过程
    从数组中的第一个元素(最后一个元素)依次与给定数值进行比较,如果与给定值相等,则进行返回相对应的数组下标(这里返回下标只是为了标记数组中有给定值),如果遍历到最后一个元素(第一个元素)仍然没有与给定值相同的数值,说明数组中没有要查找的值,可以返回一个-1(在这里-1仅仅是一个标记,表示没有找到数值)

  • 代码如下

object SequentialSearch {
  def sequentailSearch(x: Int , arr : Array[Int]) : Int = {
    var i = 0
    while (i < arr.length){
      if(x == arr(i)){
        return i
      }
      i+=1
    }
    -1
  }

  def main(args: Array[String]): Unit = {
    val i = sequentailSearch(3,Array(1,2,3,4,5,6))
    println(i)
  }

}
二分查找
  • 二分查找(BinarySearch)也称为折半查找,在使用二分查找的前提是数组中的数据已经是有序的(通常按照的是从小到大的数据排序),这是一种效率比较高的排序方法
  • 查找过程
    在有序数组中,取数组的中间值(设这个中间值叫做middle)做为比较对象,若给定的数值等于middle,则成功找到给定值,如果给定数值比middle小,则在middle的左边开始查找,若给定数值比middle大,则在middle右边进行查找,不断重复上述过程,直到查找成功,或者未查到给定值
  • 注意点
    1. 二分查找需要三个下标 开始下标(设为startIndex),结束下标(设为endIndex),中间下标(设为middleIndex)
    2. 中间下标根据开始下标和结束下标计算得出
    3. 循环退出条件: startIndex > endIndex
    4. middled取值: middleIndex = startIndex + (endIndex - startIndex)/2 因为startIndex和endIndex直接相加有可能内存溢出
    5. startIndex 和 endIndex的更新: startIndex = middleIndex+1, endIndex = middleIndex -1
  • 代码如下
object BinarySearch {
  def binarySearch(x: Int, arr: Array[Int]): Int = {

    var startIndex = 0
    var endIndex = arr.length - 1

    while (startIndex <= endIndex) {
      val middleIndex = startIndex + (endIndex - startIndex) / 2

      if (x == arr(middleIndex)) {
        return middleIndex
      }
      if (x > arr((middleIndex))) {
        startIndex = middleIndex + 1
      }
      if (x < arr(middleIndex)) {
        endIndex = middleIndex - 1
      }

    }
    -1
  }

  def main(args: Array[String]): Unit = {
    val i = binarySearch(2, Array(1, 2, 3, 4, 5, 6))
    println(i)
  }

}
插值查找
  • 插值查找 二分查找的升级版,代码上唯一的区别就是对中间值的算法做出了改变,也就是做了优化,性能上插值查找更适用于给定数值在数组中分布均匀的情况(当然这里不考虑,我们在这里只是判断这个数组中是否存在给定数值,以及返回数组中第一次出现的给定数值得下标)
  • 注意

    上图就是两种算法得本质区别
  • 代码如下
 def insertValueSearch(x: Int, arr : Array[Int]) : Int = {
    var startIndex = 0
    var endIndex = arr.length -1

    while (startIndex <= endIndex){
      val middleIndex = startIndex + (x - arr(startIndex))/(arr(endIndex) - arr(startIndex)) * (endIndex - startIndex)
      if(x == arr(middleIndex)){
        return middleIndex
      }
      if(x < arr(middleIndex)){
        endIndex = middleIndex - 1
      }
      if(x > arr(middleIndex)){
        startIndex = middleIndex + 1
      }
    }
    -1
  }

  def main(args: Array[String]): Unit = {
    val i = insertValueSearch(5, Array(1, 2, 3, 4, 5, 6))
    println(i)
  }
  • 扩展:
    除了以上的查找方法 还有
    斐波那契查找(也是在二分法的基础进行优化的 一种查找算法,主要是运用黄金比例的概念在数列中选择查找点进行查找).
    分块查找(在顺序查找的基础上进行优化的一种查找算法,主要是设计了一个索引表).
    哈希查找(通过计算元素的存储地址进行查找的算法).

你可能感兴趣的:(查找)