1.查找技術的分類。如下圖:
2.什么是順序查找呢?(無序表)
順序查找的原理很簡單,就是遍歷整個列表,逐個進行記錄的關鍵字與給定值比較,若某個記錄的關鍵字和給定值相等,則查找成功,找到所查的記錄。如果直到最后一個記錄,其關鍵字和給定值比較都不等時,則表中沒有所查的記錄,查找失敗。
時間復雜度是O(n)
3.二分查找(前提就是有序表)
二分查找的基本思想是:
在有序表中,取中間記錄作為比較對象,若給定值與中間記錄的關鍵字相等,則查找成功;若給定值小於中間記錄的關鍵字,則在中間記錄的左半區繼續查找;若給定值大於中間記錄的關鍵字,則在中間記錄的右半區繼續查找。不斷重復上述過程,直到找到為止。
從二分查找的定義我們可以看出,使用二分查找有兩個前提條件:
(1)待查找的列表必須有序(通常是從小到大的順序)。
(2)必須使用線性表的順序存儲結構來存儲數據(底層用數組實現的)。
時間復雜度是O(logn),可以看到遠遠好於順序查找的O(n)
public class BinSearch{ int min,max,mid; public static int halfSearch(int[] arr,int key){ int min=0; int max=arr.length-1; int mid=(max+min)/2; while(arr[mid]!=key){ if(key>arr[mid]){ min=mid+1; }else{ max=mid-1; } if(min>max) return -1; mid=(max+min)/2; } return mid; } public static void main(String[] args){ int[] arr={3,5,7,9,10,14};//有序的,從小到大排的 int index=halfSearch(arr,7);//要查找7,返回的是索引值 System.out.println(halfSearch(arr,7)); } }
4.索引查找
關於索引,我們很容易地聯想到數據庫中的索引,建立了索引,可以大大提高數據庫的查詢速度。
索引查找又稱為分塊查找,是一種介於順序查找和二分查找之間的一種查找方法。
分塊查找的基本思想是:
首先查找索引表,可用二分查找或順序查找(因為塊間是有序的,可以用二分查找),
然后根據塊首指針找到相應的塊,並在確定的塊中進行順序查找。
滿足兩個條件:
(1)塊內無序,每一塊內的記錄不要求有序。
(2)塊間有序,如第二塊記錄的所有關鍵字要大於第一塊,第三塊的要大於第二塊
分塊查找的時間復雜度為O(√n)。
在實現索引查找算法前需要弄清楚以下三個術語。
(1)主表。即要查找的對象。
(2)索引項。一般我們會將主表分成幾個子表,每個子表建立一個索引,這個索引就叫索引項。
(3)索引表。即索引項的集合。
同時,索引項包括以下三點。
(1)最大關鍵碼,就是存儲的每一塊中的最大關鍵字(那一塊中數字最大的那個)
(2)塊長,就是每一塊的元素個數
(3)塊首指針,就是每一塊第一個元素的指針
栗子1:
有個長度為12的無重復有序表,按折半查找法進行查找,在表內各元素等概率情況下,查找成功所需的平均比較(三元比較)的次數為(37/12)
解釋:
此題按照一顆完全二叉樹來考慮,12個結點是4層,所以為(1*1+2*2+4*3+5*4)/12
栗子2:
有如下一個類似跳表的數據結構:每層都是已經排好序的鏈表,level1層的鏈表有所有元素,levelN層的鏈表只有levelN-1的1半的元素,levelN層的結點指向levelN-1層中相同的結點。請問查找一個元素的時間復雜度是:
解釋:
這是一個類似二分查找的算法:時間復雜度O(logn)
總共有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)