查找算法-二分查找

概念

二分查找的思路是很简单的,前提是这组数据是有顺序的。 思路是从中间找一个数,判断大小,如果数比中间数大,说明在中间数到结尾的数中,如果小于,则说明在开始和中间数之间,经过多次相同操作,就可以得到我们想查找的数

时间复杂度

时间复杂度就是 O(logn)

代码实现

  1. 非递归的实现
  const testArr = []
    let i = 0
    while (i < 10000) {
      testArr.push(i)
      i++
    }
    console.log(testArr)
    let a = bsearch(testArr, testArr.length, 5554)
    console.log(a)

    function bsearch(arr, n, value) {
      let low = 0
      let hight = n - 1
      let num = 0

      while (low <= hight) {
        num++
        console.log(num)
        let mid = parseInt((low + hight) / 2)
        if (arr[mid] === value) {
          return mid
        } else if (arr[mid] < value) {
          low = mid + 1
        } else {
          hight = mid - 1
        }
      }

      return -1
    }
  1. 递归实现
   const testArr = []
    let i = 0
    while (i < 10000) {
      testArr.push(i)
      i++
    }
    console.log(testArr)
    let a = bsearch(testArr, testArr.length, 5554)
    console.log(a)

    function bsearch(arr, n, value) {
      return bsearchInternally(arr, 0, n - 1, value)
    }

    function bsearchInternally(a, low, hight, value) {
      if (low > hight) {
        return -1
      }
      let mid = parseInt((low + hight) / 2)
      if (a[mid] === value) {
        return mid
      } else if (a[mid] < value) {
        return bsearchInternally(a, mid + 1, hight, value)
      } else {
        return bsearchInternally(a, 0, hight - 1, value)
      }
    }
二分查找应用场景的局限性
  1. 二分查找依赖的是顺序表结构,简单点说就是数组。
  2. 二分查找针对的是有序数据
  3. 数据量太小不适合二分查找
  4. 数据量太大也不适合二分查找 (数组需要连续的存储空间,太大的数据需要开辟很大的内存)
变形问题
1. 查找第一个等于给定值的元素
2. 查找最后一个等于给定值的元素
3. 查找第一个大于等于给定值的元素
4. 查找最后一个小于等于给定值的元素
  1. 查找第一个等于给定值的元素

 const testArr = []
    let i = 0
    while (i < 10000) {
      if (i === 5554) {
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
      } else {
        testArr.push(i)
      }
      i++
    }
    console.log(testArr)
    let a = bsearch(testArr, testArr.length, 5554)
    console.log(a)

    function bsearch(a, n, value) {
      let low = 0;
      let high = n - 1;
      while (low <= high) {
        let mid = low + ((high - low) >> 1);
        if (a[mid] > value) {
          high = mid - 1;
        } else if (a[mid] < value) {
          low = mid + 1;
        } else {
          // 等于的时候再做一次处理
          if ((mid == 0) || (a[mid - 1] != value)) return mid;
          else high = mid - 1;
        }
      }
      return -1;
    }

  1. 查找最后一个等于给定值的元素
const testArr = []
    let i = 0
    while (i < 10000) {
      if (i === 5554) {
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
      } else {
        testArr.push(i)
      }
      i++
    }
    console.log(testArr)
    let a = bsearch(testArr, testArr.length, 5554)
    console.log(a)

    function bsearch(a, n, value) {
      let low = 0;
      let high = n - 1;
      while (low <= high) {
        let mid = low + ((high - low) >> 1);
        if (a[mid] > value) {
          high = mid - 1;
        } else if (a[mid] < value) {
          low = mid + 1;
        } else {
          // 等于的时候再做一次处理
          if ((mid == n - 1) || (a[mid + 1] != value)) {
            return mid;
          } else {
            low = mid + 1;
          }
        }
      }
      return -1;
    }
    
  1. 查找第一个大于等于给定值的元素

    const testArr = []
    let i = 0
    while (i < 10000) {
      if (i === 5554) {
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
      } else {
        testArr.push(i)
      }
      i++
    }
    console.log(testArr)
    let a = bsearch(testArr, testArr.length, 5554)
    console.log(a)

    function bsearch(a, n, value) {
      let low = 0;
      let high = n - 1;
      while (low <= high) {
        let mid = low + ((high - low) >> 1);
        if (a[mid] >= value) {
          if ((mid == 0) || (a[mid - 1] < value)) return mid; else high = mid - 1;
        } else {
          low = mid + 1;
        }
      }
      return -1;
    }

  1. 查找最后一个小于等于给定值的元素
 const testArr = []
    let i = 0
    while (i < 10000) {
      if (i === 5554) {
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
        testArr.push(i)
      } else {
        testArr.push(i)
      }
      i++
    }
    console.log(testArr)
    let a = bsearch(testArr, testArr.length, 5554)
    console.log(a)

    function bsearch(a, n, value) {
      let low = 0;
      let high = n - 1;
      while (low <= high) {
        let mid = low + ((high - low) >> 1);
        if (a[mid] > value) {
          high = mid - 1;
        } else {
          if ((mid == n - 1) || (a[mid + 1] > value)) return mid; else low = mid + 1;
        }
      }
      return -1;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值