演算法(一):二分查詢法

CodeInfo發表於2018-07-21

演算法基礎:

一、大O表示法:

指示演算法的速度有多快,用於指出隨數量的增大,演算法的所需步驟增加的速度,常見的大O執行時間(時間複雜度):
O(1)表示常數階時間複雜度
O(log n),也叫對數時間複雜度,這樣的演算法包括二分查詢。
O(n),也叫線性階時間複雜度,這樣的演算法包括簡單查詢。
O(n * log n), (n*對數複雜度)
O(n^2),平方階時間複雜度
O(n!),階乘階時間複雜度
複製程式碼

n越來越大時,演算法效率圖解:

演算法(一):二分查詢法

要點

  • 1.二分查詢法只適用於從有序的佇列中進行查詢(比如數字和字母等),將佇列排序後再進行查詢

  • 2.二分查詢法的執行時間為對數時間O(㏒₂n) ,即查詢到需要的目標位置最多只需要㏒₂n步,假設從[0,99]的佇列(100個數,即n=100)中尋到目標數30,則需要查詢步數為㏒₂100 , 即最多需要查詢7次( 2^6 < 100 < 2^7)

  • 3.簡單查詢(遍歷查詢)的執行時間為線性時間O(n), 假設從[0,99]的佇列中(n=100)尋到目標數30,則最多需要查詢步數為100步

  • 4.對於容器內數量很少的情況下,2種查詢也許沒啥差別,當數量大的情況下,差別就很大,比如假設查詢比較步驟一次需要1秒,當容量數目為100000時,O(n)需要100000秒即約27.8小時,而logn只需要 2^16 < 100000 < 2^17,即17秒,這差距非常的大

  • 5.時間複雜度都是針對最壞的情況所表示的,表示最多需要多少步

案例

從1~99的容器內,找出指定的數字;

java實現:
A:簡單查詢法,即遍歷查詢,全部遍歷直到找到指定的數便停止

/**
 * 簡單查詢
 * @param array    傳入存放全部資料的容器
 * @param target   需要查詢的目標數
 * @return
 */
public Integer search(Integer[] array,int target){
    for(int i=0;i<array.length;i++){
        if(array[i] == target){
            return i;
        }
    }
    return null;
}

B:二分查詢法

/**
 * 二分查詢法
 * @param array   傳入存放全部資料的容器
 * @param target  需要查詢的目標數
 * @return
 */
public Integer searchDichotomy(Integer[] array, int target){
    int low =0;
    int hight=array.length-1;
    while(low<=hight){                 //遍歷還沒結束
        int mid = (low+hight)/2;       //取中間值mid點位置
        if(array[mid]==target){        //尋找到目標數
            return mid;
        }
        if(array[mid] > target){        //如果中間值大於目標數,則將highr點位置移動mid位置左邊
           hight = mid-1;
        }
        if(array[mid] < target){       //如果中間值小於目標數,則將low點位置移動mid位置右邊
            low = mid+1;
        }
    }
    return null;
}
複製程式碼

圖解:

假設容器中為[1,99],共99個數 必須明白因為時間複雜度是針對最壞情況的,二分查詢所需最多為7步,簡單遍歷法最多為99步(當查詢的是數99);

根據實際需要查詢的數,所消耗的步驟不一定一樣,但都不會超過時間複雜度

步驟圖解如下所示([1,99],即n=99,查詢的數為30):

演算法(一):二分查詢法

時間複雜度推算過程:

參考:https://blog.csdn.net/frances_han/article/details/6458067 二分查詢的基本思想是將n個元素分成大致相等的兩部分,去a[n/2]與x做比較,如果x=a[n/2],則找到x,演算法中止;如果x<a[n/2],則只要在陣列a的左半部分繼續搜尋x,如果x>a[n/2],則只要在陣列a的右半部搜尋x. 時間複雜度無非就是while迴圈的次數! 總共有n個元素, 漸漸跟下去就是n,n/2,n/4,....n/2^k,其中k就是迴圈的次數 由於你n/2^k取整後>=1 即令n/2^k=1 可得k=log2n,(是以2為底,n的對數) 所以時間複雜度可以表示O()=O(logn)

有興趣共同進步可以掃描關注微信訂閱號

演算法(一):二分查詢法

相關文章