zoukankan      html  css  js  c++  java
  • 二分查找时间复杂度推导

      二分查找是一个非常常用且简洁的查找算法,相信很多人也知道它的时间复杂度是logN,但是我看网上的大多数博客给出的所谓推导过程都十分不严谨,于是我花了些时间自己写了推导过程。

    首先上二分查找的代码:

        public int find(int x, int[] data) {
            return find(x, data, 0, data.length - 1);
        }
    
        /**
         * 查找元素下标,没找到返回-1
         * @param x 待查找元素
         * @param data 有序的元素数组
         * @createTime:2017年3月4日 
         * @author: gaojiabao
         */
        private int find(int x, int[] data, int low, int high) {
            int mid = (low + high) >> 1;
            if (x == data[mid]) {
                return mid;
            } else if (x > data[mid]) {
                low = mid + 1;
            } else if (x < data[mid]) {
                high = mid - 1;
            }
    
            if (low == high) {
                if (x == data[low]) {
                    return low;
                } else {
                    return -1;
                }
            } else {
                return find(x, data, low, high);
            }
        }

    下面是推导过程:

    假设数据的规模为N(即每次调用时的high-low),程序执行的比较次数表示为C(N),假设程序查找的是一个不存在的数据,则此时执行的次数是最多的:

    执行第一次时,有:

    1代表执行了一次x和data[mid]的比较过程,代表下一次递归调用find方法时high-low的值,也就是新的数据规模每次较少一半以上。

    递归上面的公式,有:

    我们知道每一个整数都可以表示为2i+k的形式,如1=20+0,5=22+1,10=23+2,因此

    设N=2i+k

    令上面公式的n=i,则有:

    因为N=2i+k,则有i=⌊lgN⌋,因此:

    因为我们一直以来的假设是要查找到的元素是找不到的,所以现在的情况是C(N)最大的情况,对于一般情况,则有:

    因此二分查找的时间复杂度是logN。 

  • 相关阅读:
    逆向笔记——PE文件相对虚拟地址(RVA)转文件偏移地址(FOA)
    逆向笔记——在PE任意一个节中添加代码
    FFT的物理意义
    Hilbert-Huang Transform: matlab 希尔伯特-黄变换: matlab实现
    交叉验证 Cross validation
    AAL template: ROI to brain lobe
    Types of intraclass correlation coefficience (ICC)
    统计:P值 & α值
    Notes: sensitivity & specificity
    Meet Github
  • 原文地址:https://www.cnblogs.com/sheeva/p/6501591.html
Copyright © 2011-2022 走看看