改寫二分搜尋演算法
一、實踐題目
改寫二分搜尋演算法
二、問題描述
設a[0:n-1]是已排好序的陣列,請改寫二分搜尋演算法,使得當x不在陣列中時,返回小於x的最大元素位置i和大於x的最小元素位置j。當搜尋元素在陣列中時,i和j相同,均為x在陣列中的位置。
輸入格式:
輸入有兩行:
第一行是n值和x值; 第二行是n個不相同的整陣列成的非降序序列,每個整數之間以空格分隔。
輸出格式:
輸出小於x的最大元素的最大下標i和大於x的最小元素的最小下標j。當搜尋元素在陣列中時,i和j相同。 提示:若x小於全部數值,則輸出:-1 0 若x大於全部數值,則輸出:n-1的值 n的值
輸入樣例:
在這裡給出一組輸入。例如:
6 5
2 4 6 8 10 12
輸出樣例:
在這裡給出相應的輸出。例如:
1 2
三、演算法描述
我們原來的二分查詢演算法BiSearch(int array [ ], int n, int key)尋找的是在序列(array)中存在的某個數(key),為了達到這一目的,我們需要定義左右兩個指標(left和right),如果找不到,最後的指標將會是 left > right ,根據題目要求,實際就是在二分搜尋的基礎上增加若尋找不到目標元素,返回 left 指標與 right 指標所指向的元素下標。要注意最後找不到時left指向的是大於查詢目標key的最小下標。
綜上,在查詢過程中,若查詢到目標元素,則直接輸出兩次mid,結束查詢,否則,則在查詢完畢後,分別輸出right 與 left指標指向的下標
四、演算法分析
時間複雜度:二分查詢是將陣列 array 從中間切成大致相等的兩部分,取 array[n/2] 與key做比較,如果 target=a[n/2] ,則找到 key 。因為每次規模都小一半,我們可以假設查找了 k 次,則 2^k = n,所以 k = log n,所以時間複雜度為O(log n)。
空間複雜度:本題採用的是非遞迴的做法,而且變數不會隨著 n 而變化,所以空間複雜度為O(1)。
五、心得體會
之前一直以為二分查詢就十分簡單,後來才發現原來有這麼多的變通,不過在理解好最高根本的二分思想之後,也就都迎刃而解了。在做這道題的過程一開始理所當然以為left就是小於key的最大元素下標,後來人肉cpu跑了一遍才發現並不是。所以對於一些不理解的演算法,我認為自己跟著演算法一步一步算一遍有助於更好地理解演算法。