雖是讀書筆記,可是如轉載請註明出處 http://segmentfault.com/blog/exploring/
.. 拒絕伸手複製黨算法
想更一進步的支持我,請掃描下方的二維碼,你懂的~segmentfault
根據給定的關鍵字值,在一組數據中肯定一個其關鍵字值等於給定關鍵字值的數據元素。
若存在這樣的數據元素,則稱查找是成功的;不然稱查找不成功。一組待查數據元素的集合又稱爲查找表。函數
關於查找,通常要明確下述兩個問題。
(1)查找的方法
按照數據元素的組織方式決定採用的查找方法;爲了提升查找方法的效率,又要求數據元素採用某些特殊的組織方式。所以,在研究各類查找方法時,必須弄清各類方法所適用的組織方式。
(2)查找算法的評價
標準有兩個:時間複雜度和空間複雜度。在查找算法中,基本運算是給定值與關鍵字值的比較,因此,咱們引出一個成爲平均查找長度(ASL)的概念,做爲評價查找算法好壞的依據。spa
對於含有 n 個數據元素的查找表,查找成功時的平均查找長度爲:
n
ASL = ∑ Pi* Ci
i=1
其中:Pi 爲查找表中第 i 個數據元素的機率,Ci 爲查找第 i 個數據元素時需比較的次數。.net
順序表的幾種查找算法:
順序查找、折半查找和分塊查找指針
從第一個元素開始,逐個把元素的關鍵字值和給定值比較,若某個元素的關鍵字值和給定值相等,則查找成功;不然,若直至第 n 國記錄都不相等,說明不存在知足條件的數據元素,查找失敗。code
查找表的存儲結構:
既適用於順序存儲結構,也適用於鏈式存儲結構。對象
平均查找長度 ASL 在等機率的狀況下
n n
ASL = ∑ Pi*Ci =(∑(n-i+1) )/n =n+1/2
i=1 i=1
平均查找長度 ASL 在等機率的狀況下
ASL ≤n/2
優勢:
-對結點的邏輯次序 (沒必要有序) 和存儲結構 ( 順序、鏈表都可)無要求;
-當序列中的記錄 「基本有序」 或 N 值較小時,是較好的算法;
缺點:
-ASL 較長
順序表查找算法的特色是簡單、容易實現.但其缺點也是不容忽視的,那就是要預先分配最大存儲空間、頻繁地插入、刪除操做效率不好。blog
先將欲查找的數值和該組數據的中間位置上的數值比較,當小於中間值時,再向前查詢,大於中間值時向後查詢,繼續取前面(或後面)一半數據的中間值進行比較,若是小於再向前查詢,大於就向後查詢,一直到找到或查詢完畢爲止。排序
折半查找的過程看,以有序表的中間記錄做爲比較對象,並以中間記錄將表分割爲兩個子表,對子表繼續上述操做。因此,對錶中每一個記錄的查找過程,可用二叉樹來描述,二叉樹中的每一個結點對應有序表中的一個記錄,結點中的值爲該記錄在表中的位置。一般稱這個描述折半查找過程的二叉樹爲折半查找斷定樹。
(1)折半查找斷定樹是一顆BST,即每一個節點的值均大於其左子樹上全部節點的值,小魚右子樹上全部節點的值;
(2)折半查找斷定樹中的結點都是查找成功的狀況,將每一個結點的空指針指向一個實際上並不存在的結點——稱爲外結點,全部外結點便是查找不成功的狀況,如圖(e)所示。若是有序表的長度爲n,則外結點必定有n+1個。
(3)在折半查找斷定樹中,某結點所在的層數便是查找該結點的比較次數,整個斷定樹表明的有序表的平均查找長度即爲查找每一個結點的比較次數之和除以有序表的長度。
例如,長度爲10的有序表的平均查找長度爲: ASL = (1×1+2×2+3×4+4×3)/10=29/10
在折半查找斷定樹中,查找不成功的過程就是走了一條從根節點到外部節點的路徑,和給定值進行比較的關鍵字個數等於該路徑上內部結點個數
。整個斷定樹表明的有序表在查找失敗時的平均查找長度即爲查找每一個外結點的比較次數之和除之外結點的個數。例如,長度爲10的有序表在查找失敗時的平均查找長度爲: ASL=(3×5+4×6)/11=39/11
總結說來:
折半查找成功的ASL與序列中的具體元素無關
,只取決於序列中元素的數目
。因此,折半查找斷定樹只與查找表中元素的數目有關
。
採用二分查找方法查找長度爲n的線性表時,每一個元素的平均查找長度爲O(logn)
1.順序查找法適合於存儲結構爲_______的線性表。 A. 散列存儲 B. 順序存儲或連接存儲 C. 壓縮存儲 D. 索引存儲 2.使用二分查找法時,要求查找表中各元素的鍵值必須是_______排列的。 A.遞增或遞減 B.遞增 C. 遞減 D.無序 3.採用二分查找方法查找長度爲n的線性表時,每一個元素的平均查找長度爲_______。 A. O(n2) B. O(nlog2n) C.O(n) D. O(log2n) 4. 有一個長度爲12的有序表,按二分查找法對該表進行查找,在表內各元素等機率狀況下,查找成功所需的平均比較次數爲________。 A. 35/12 B. 37/12 C. 39/12 D, 43/12 5.用n個鍵值構造一棵二排序樹,該二叉排序樹的最低高度爲______。 A. n/2 B. n C. [log2n] D.[log2+1] 1.B 2. A 3. D 4. B 5. D
BST(最基本),紅黑樹(更平衡查找效率更高的BST)
⑴ 當二叉排序樹不空時,首先將給定值 k 與根結點的關鍵字進行比較,若相等則查找成功;
⑵ 若給定值 k 小於根結點的關鍵字,則下一次與左子樹的根結點的關鍵字進行比較,若給定值 k 大於根結點的關鍵字,則與右子樹的根接到的關鍵字進行比較。
如此遞歸的進行下去直到某一次比較相等,查找成功。若是一直比較到樹葉都不等,則查找失敗。
總結說來:
二叉排序樹查找成功的平均查找長度取決於二叉排序樹的形狀,而二叉排序樹的形狀既與結點數目有關,更取決於創建二叉排序樹時結點的插入順序。
也叫散列查找,different from above methods,它的查找並不創建在比較基礎上。哈希查找則是經過計算存儲地址的方法進行查找的。
哈希查找是創建在哈希表的基礎上,它是線性表的一種重要存儲方式和檢索方法。在哈希表中能夠實現對數據元素的快速檢索
若已知哈希函數及衝突處理方法,哈希表的創建步驟以下:
Step1.取出一個數據元素的關鍵字 key,計算其則哈希表中的存儲地址 D=H(key)。若存儲地址爲 D 的存儲空間尚未被佔用,則將該數據元素存入;不然發生衝突,執行 Step2。
Step2. 根據規定的衝突處理方法,計算關鍵字爲 key 的數據元素之下一個存儲地址。若該存儲地址的存儲空間沒有被佔用,則存入;不然繼續執行 Step2,直到找出一個存儲空間沒有被佔用的存儲地址爲止。
解決碰撞的方法:
1. 拉鍊法
:
2. 開放尋址法
$$hash_i =( hash(key) + di ) mod m$$
其中hash(key)爲散列函數,m爲散列表長,d_i爲增量序列,i爲已發生碰撞的次數。
增量序列可有下列取法:線性探測
平方探測
僞隨機數探測
3. 雙重散列 h(k,i) = (h1(k) + i * h2(k)) mod n
4 再散列
⑴線性探測再散列 { D = H(key); ND = (D+di)%m; di 取 1,2,3,……,m-1 線性探測再散列處理衝突的基本思想: 若數據元素在存儲地址 D 發生衝突,則放到存儲地址(D+1)%m;若又發生衝突則放到存儲地址(D+2)%m;若再發生衝突則放到存儲地址(D+3)%m;……;直到碰到第一個爲空的存儲地址(D+i)%m,則將數據元素存放在該存儲空間。 ⑵二次探測再散列 { D = H(key); ND = (D+di)%m; di 取 1*1,-1*1,2*2,-2*2,……,K*K,-K*K (K≤m/2) 值得提醒的是,對利用開放地址法查了衝突所產生的哈希表中刪除一個元素,不能簡單地直接刪除,由於這樣將截斷其它具備相同哈希地址的元素的查找地址,因此應設定一個特殊的標誌以代表該元素已被刪除。
散列表的查找過程和造表過程一致。
查找過程爲:對於待查值,計算散列地址,若散列地址內爲空標記,則查找失敗;若待查值與該地址內記錄關鍵字相等,則查找成功。 不然,求下一地址,直至散列地址爲空標記,或已搜索了表中的全部單元(查找不成功),或待查值與該地址內記錄關鍵字相等(查找成功)爲止。 決定散列表平均查找長度的因素主要有散列函數、處理衝突的方法和查找表記錄數
作到一道求 哈希表查找成功與查找不成功 狀況下平均查找長度的計算問題,迷惑了好一會,在這裏總結下來: 首先,你要明白的是平均查找長度求的是指望,那麼你就按照求指望的方法來求平均查找長度吧,千萬記着指望怎麼求平均查找長度就怎麼求啊。 題目: 在地址空間爲 0~16 的散列區中,對如下關鍵字序列構造兩個哈希表: {Jan, Feb, Mar, Apr, May, June, July, Aug, Sep, Oct, Nov, Dec} (1) 用線性探測開放地址法處理衝突; (2) 用鏈地址法(開散列存儲)處理衝突 並分別求這兩個哈希表在等機率狀況下查找成功和查找不成功時的平均查找長度。設哈希函數爲 H(key) = i/2, 其中 i 爲關鍵字中第一個字母在字母表中的序號, 以下: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 解決以下: (1) 線性探測進入散列區的次序以下,X 表明衝突,要找下一個空格 Jan -> 5 Feb -> 3 Mar -> 6 Apr -> 0 May -> 6X -> 7 June -> 5X -> 6X -> 7X -> 8 July -> 5X -> 6X -> 7X -> 8X -> 9 Aug -> 0X -> 1 Sep -> 9X -> 10 Oct -> 7X -> 8X -> 9X -> 10X -> 11 Nov -> 7X -> 8X -> 9X -> 10X -> 11X -> 12 Dec -> 2
很明顯,查找成功時,查找 Jan、Feb、Mar 等僅須要一次,其他的也能夠由上面看出來 因此查找成功時平均查找長度 (ASL) = (1 + 1 + 1 + 1 + 2 + 4 + 5 + 2 + 2 + 5 + 6 + 1) / 12 = 31/12 = 2.58 爲何是除以 12 呢?由於查找成功的狀況總共有 12 種啊 查找不成功時呢?什麼是查找不成功呢?查找不成功就是從查找位置開始直到一個位置爲空須要比較的次數。 首先,26/2=13,也就是說查找不成功的狀況也只能出如今 0~13 之間,只有這 14 種狀況。 舉個例子來講,查找 Aay 吧,根據 hash 表,與 Apr 比較不匹配,接着與 Aug 比較又是不匹配,接着與 Dec 比較又是不匹配,又與 Feb 比較又是不匹配,到了 4 位置的時候爲空了,即 4 上內容與 nullkey 比較,結果爲空,因此查找 Aay 失敗,查找長度爲 5。同理也能計算其餘的。 最終平均查找失敗時平均查找長度爲(5+4+3+2+1+9+8+7+6+5+4+3+2+1)/14=60/14。注意啊,這裏是除以 14 啊。(這是求指望的方法啊) (2) 鏈地址法 0 之下有 Apr, Aug 2 之下有 Dec 3 之下有 Feb 5 之下有 Jan, June, July 6 之下有 Mar, May 7 之下有 Oct, Nov 9 之下有 Sep 查找成功時候,查 Apr, Dec, Feb, Jan, Mar, Oct, Sep 各需 1 次,查 Aug, June, May, Nov 各需 2 次,查 July 需 3 次。 因此查找成功時平均查找長度 (ASL) = (1 * 7 + 2 * 4 + 3 * 1) / 12 = 18/12 = 1.5 查找失敗時平均查找長度:舉個例子吧,查找 Boy,2/2=1,而 1 的地方的指針爲空,就不用比較就能夠知道不存在,查找產度爲 0。查找 Aay,與 Apr 比較不匹配,與 Aug 比較不匹配,同時,Aug 指向下一個節點的指針爲空,就能夠知道查找失敗,查找長度爲 2。 因此查找失敗的平均查找長度:(2+1+1+3+2+2+1)/14=12/14。