zoukankan      html  css  js  c++  java
  • 二分搜索

    计算机科学中,二分搜索英语:binary search),也称折半搜索英语:half-interval search)、对数搜索英语:logarithmic search),是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

    来自 <https://zh.wikipedia.org/wiki/%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2%E7%AE%97%E6%B3%95>

    时间复杂度

    折半搜索每次把搜索区域减少一半,时间复杂度为O(log n)。(n代表集合中元素的个数)

    空间复杂度

    O(1)。虽以递归形式定义,但是尾递归,可改写为循环。

    来自 <https://zh.wikipedia.org/wiki/%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2%E7%AE%97%E6%B3%95>

    实现:Java版本(循环和递归2个版本)

     1 package com.yan.algorithm;
     2 /**
     3  * 二分搜索、折半查找:适用于在有序数组中查找某个值,时间复杂度为O(log n),空间复杂度为O(1)
     4  * @author Yan
     5  *
     6  */
     7 public class BinarySearch {
     8 
     9     public BinarySearch() {
    10     }
    11 
    12     static int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7 };
    13 
    14     public static void main(String[] args) {
    15         BinarySearch bSearch = new BinarySearch();
    16         int rs1 = bSearch.binarySearch(arr, 1);
    17         int rs2 = bSearch.binarySearch2(arr, 1, 0, arr.length - 1);
    18         System.out.println(rs1);
    19         System.out.println(rs2);
    20     }
    21 
    22     public int binarySearch(int[] arr, int k) {
    23         if (arr == null) {
    24             return -1;
    25         }
    26         int left = 0;
    27         int right = arr.length - 1;
    28         int mid = (left + right) >> 1;
    29         while (left <= right) {
    30             if (arr[mid] == k) {
    31                 return mid + 1;
    32             } else if (k > arr[mid]) {
    33                 left = mid + 1;
    34             } else {
    35                 right = mid - 1;
    36             }
    37             // 若为 mid=(left+right)/2,会发生溢出。
    //问题会出现在当low+high的结果大于表达式结果类型所能表示的最大值时,这样,产生溢出后再/2是不会产生正确结果的,而low+((high-low)/2)不存在这个问题。
    38              mid = left + ((right - left) >> 1);
    39         }
    40 
    41         return -1;
    42     }
    43 
    44     /**
    45      * 递归版本
    46      * 
    47      * @param arr
    48      * @param k
    49      * @param left
    50      * @param right
    51      * @return
    52      */
    53     public int binarySearch2(int[] arr, int k, int left, int right) {
    54         if (left > right) {
    55             return -1;
    56         }
    57         // int mid = (right + left) >> 1;
    58         //// 若为 mid=(left+right)/2,会发生溢出。
    //问题会出现在当low+high的结果大于表达式结果类型所能表示的最大值时,这样,产生溢出后再/2是不会产生正确结果的,而low+((high-low)/2)不存在这个问题。
    59         
    60         int mid = left + ((right - left) >> 1);
    61         if (k > arr[mid]) {
    62             // return 函数自身,则每层都会返回底层所返回的值,所以会返回最后找到的那个mid。
    63             return binarySearch2(arr, k, mid + 1, right);
    64         }
    65         if (k < arr[mid]) {
    66             return binarySearch2(arr, k, left, mid - 1);
    67         }
    68         return mid + 1;
    69     }
    70 }
  • 相关阅读:
    HDU 5861 Road (线段树)
    HDU 5857 Median (推导)
    HDU 5858 Hard problem (数学推导)
    HDU 5867 Water problem (模拟)
    UVALive 7455 Linear Ecosystem (高斯消元)
    A bug about RecipientEditTextView
    当Activity出现Exception时是如何处理的?
    FontSize sp 和 dp 的区别
    Android的Overlay机制
    关于控件问题的分析
  • 原文地址:https://www.cnblogs.com/yanspecial/p/5557451.html
Copyright © 2011-2022 走看看