1. 程式人生 > >MIT演算法導論——第七講.雜湊表

MIT演算法導論——第七講.雜湊表

從作用上來講,構建雜湊表的目的是把搜尋的時間複雜度降低到O(1),考慮到一個長度為n的序列,如果依次去比較進行搜尋的話,時間複雜度是θ(n),或者對其先進行排序然後再搜尋會更快一些,但這兩種方法都不是最快的方法。
第一個話題:

計算機裡面所有儲存的內容都是數字,因此我們研究對數字構建雜湊表就夠了。先來考慮一下,一個好的雜湊函式H需要哪些特點:

1.雜湊函式的產生的鍵值要儘可能的均勻,不要出現聚集效應,也就是產生的各種h(k)要儘量的等概率的分佈到雜湊表的m個槽裡去,當然,如果已經知道了輸入的型別,我們可以設計出比較好的雜湊函式,但是每一個雜湊函式都有可能遇到一個特別針對他的輸入,以至於所有計算的健值都指向同一個槽。
(一個雜湊函式是否均勻的定義:x,y是兩個不同的健值,雜湊表的長度是m,P{h(x) = h(y)} =1/m ) 
2.雜湊函式本身不能太複雜,以至於計算的時間過長。

例,一些簡單的雜湊函式:
1.直接雜湊 h(k)=k,不會發生碰撞,但是佔用空間大,沒有意義
2.除法雜湊 h(k)=k mod m ,m的取值很有講究,不能去2和10的冪,這樣很多內容都被mod掉了,而且不能取得太小等等等,可以考慮去一個合適的質數。由於計算機裡經常用2和10的冪,不是很好用質數,而且還是除法,所以這種雜湊效率也不是很高
3.乘法雜湊,假設所有的key都是整數,m=2^r ,計算機字長是w,那麼構建h(k)=(A*k mod 2^w) rsh (w-r) 其中rsh是右移的意思,A的大小是2^(w-1)<A<2^w 這個雜湊函式的好處是,最後的取得h(k)實際上和每一位上的k值都相關,而A和2^w這兩個數是互質的,所以想象一個輪盤,周長是2冪,A肯定不是周長的倍數,k是轉了多少圈,那麼最後的h(k)就會有可能落到輪盤的任意位置。

第二個話題:
就像之前提到的,無論設計一個怎樣的雜湊函式,碰撞都難以避免,那麼如何來解決碰撞的問題呢?主要有以下兩種方法:
1.連結法,每一次碰撞都新增一個連結串列,這樣做會增加雜湊表的大小,最壞的情況會導致所有的值都指向同一個槽,然後雜湊表變成了一個連結串列,我們的查詢也變成了連結串列的查詢。
2.開放定址法,在不增加雜湊表容量的情況下,繼續對該表進行“探測”,直到找到一個空位置把內容放進去。 wikipedia裡面對此的解釋是這樣的(Open addressing, or closed hashing, is a method of collision resolution in hash tables

. With this method a hash collision is resolved by probing

分析第一種方法——連結串列法:

在最壞的情況下,那就是所有的h(k)都指向了同一個槽,那麼雜湊表實際上就是一個連結串列,在連結串列中查詢一個值的時間複雜度是θ(n),在最好的情況下,沒有發生碰撞那麼時間為θ(1)。定義α=n/m為雜湊表的裝載因子,一次成功的搜尋平均用時θ(1+α/2)1表示計算H的時間,α/2表示在連結串列中所用的平均時間,所以如果n=O(m)那麼α就是常數,在這個雜湊表中搜索的時間就為θ(1),同時,考慮平均情況下的最壞情況的搜尋,時間為θ(1+α),

分析第二種方法——“開放定址”(封閉雜湊)
這種方法主要通過“探尋”來在雜湊表中尋找下一個空位置,把值存進去,查詢的時候也採用同樣的方法,一步一步查詢到目標鍵值。
探尋的方法有:
1.線性探尋
2.非線性探尋
3.雙重雜湊探尋
4.偽隨機序列探尋
這些方法都有一定的侷限性,有可能造成頂級或者次級聚集
現在來分析開放定址的效率,首先給出理論:對於一個開放定址的雜湊表,α=n/m<1,那麼一次不成功搜尋的預期探尋次數為1/(1-α).
由此可見,如果α=50% 那麼預期探尋次數為2,如果α=90%,預期探尋次數將會顯著升高到10,因此在這種策略下,α的大小至關重要(聯想到同一天生日的問題,也是這個道理),在工程上某些採用此策略的雜湊表會強制α小於75%,如果超過這個值會自動擴充雜湊表。
預期探尋次數1/(1-α)是怎樣算出來的,如下:
1.首先,查詢一個值至少需要1次探尋
2.有n/m的可能性會發生碰撞,我們需要第二次探尋
3.有(n-1)/(m-1)的可能性第二次探尋也發生了碰撞
……
觀察到(n-i)/(m-i)<α i=1,2,3……n


相關推薦

MIT演算法導論——.

從作用上來講,構建雜湊表的目的是把搜尋的時間複雜度降低到O(1),考慮到一個長度為n的序列,如果依次去比較進行搜尋的話,時間複雜度是θ(n),或者對其先進行排序然後再搜尋會更快一些,但這兩種方法都不是最快的方法。 第一個話題: 計算機裡面所有儲存的內容都是數字,因此我

演算法導論 章:快速排序 筆記(快速排序的描述、快速排序的效能、快速排序的隨機化版本、快速排序分析)

快速排序的最壞情況時間複雜度為Θ(n^2)。雖然最壞情況時間複雜度很差,但是快速排序通常是實際排序應用中最好的選擇,因為它的平均效能很好。它的期望執行時間複雜度為Θ(n lg n),而且Θ(n lg n)中蘊含的常數因子非常小,而且它還是原址排序的。 快速排序是一種排序演算法,對包含n個數的

MIT演算法導論三節筆記——分治思想

這一節主要講了分治思想,首先我應該向大家推薦兩本參考書:《演算法導論》和《演算法概論》,很多講課內容都在這兩本書上,但不限於這兩本書。 這次視訊中設計的演算法如下: 歸併排序 折半查詢 求X的冪 斐波那契數,包括1. 遞迴演算法;2. 用儲存每一個計算過的斐波那契數的方式

演算法導論 章快速排序與隨機快速排序

view plaincopy to clipboardprint?#include <iostream>   #include <cstdlib>   #include <time.h>   using namespace std;    

演算法導論章課後答案

7.1-1 參照圖7-1的方法,說明PARTITION在陣列A={13,9,9,5,12,8,7,4,21,2,6,11}上的操作過程。 A={13,19,9,5,12,8,7,4,21,2,6,11}   ={13,19,9,5,12,8,7,4,21,2,6,11}  

PE格式,重定位

作者:IBinary 出處:http://www.cnblogs.com/iBinary/ 版權所有,歡迎保留原文連結進行轉載:) 一丶何為重定位(注意,不是重定位表格) 首先,我們先看一段程式碼,比如呼叫Printf函式,使用OD檢視. 那麼大家有沒有想過這麼一個問題,函式的字串

與字串(小象)

目錄   雜湊表基礎知識 雜湊表定義 1、字元雜湊 2、雜湊表排序整數 3、拉鍊表解決衝突,構造雜湊表 4、STL map中的常用操作 409、最長迴文串 290、單詞模式 49、字母異位詞分組 3、無重複字元的最長子串(滑動視窗的機制) 1

【資料結構與演算法】【查詢】的程式碼實現

// Filename: hash.c #include <stdio.h> #include <stdlib.h> #include "public.h" #include "hash.h" // 雜湊表初始化,雜湊表長度為size int InitHashTable(HashT

淺談演算法和資料結構:

在前面的系列文章中,依次介紹了基於無序列表的順序查詢,基於有序陣列的二分查詢,平衡查詢樹,以及紅黑樹,下圖是它們在平均以及最差情況下的時間複雜度: 可以看到在時間複雜度上,紅黑樹在平均情況下插入,查詢以及刪除上都達到了lgN的時間複雜度。 那麼有沒

演算法與資料結構基礎 - (Hash Table)

Hash Table基礎 雜湊表(Hash Table)是常用的資料結構,其運用雜湊函式(hash function)實現對映,內部使用開放定址、拉鍊法等方式解決雜湊衝突,使得讀寫時間複雜度平均為O(1)。   HashMap(std::unordered_map)、HashSet(std::

MIT演算法導論公開課全域湊和完全

全域雜湊            對於任意雜湊函式而言,都存在一個不好的健集,使得所有的健都會雜湊到同一個槽裡去,那麼如何解決這種情況呢?如何防止對某個鍵集永遠有較差的表現?如何防止競爭對手使用這個鍵集來降低你的效能表現? 一個詞解決這個問題 —— 隨機! 全域雜湊的方法

演算法導論 十一章:散列表 筆記(直接定址、散列表、通過連結法解決碰撞、函式、開放定址法、完全

前面討論的各種資料結構中,記錄在各種結構中的相對位置是隨機的,和在記錄的關鍵字之間不存在有確定的關係,因此在查詢記錄是需要進行一系列和關鍵字的比較。而理想的情況是不希望進行任何的比較,一次存取便能得到所查記錄。那就必須在記錄的儲存位置和它的關鍵字之間建立一種確定的關係f,使每個關鍵字和結構中有一

查詢演算法 淺談演算法和資料結構: 二叉查詢樹 淺談演算法和資料結構: 十一

閱讀目錄 1. 順序查詢 2. 二分查詢 3. 插值查詢 4. 斐波那契查詢 5. 樹表查詢 6. 分塊查詢 7. 雜湊查詢   查詢是在大量的資訊中尋找一個特定的資訊元素,在計算機應用中,查詢是常用的基本運算,例如編譯程式中符號表的查詢。本文

資料結構和演算法版(陣列、棧、佇列、連結串列、遞迴、排序、二叉樹、紅黑樹、堆、)Java版

查詢和排序是最基礎也是最重要的兩類演算法,熟練地掌握這兩類演算法,並能對這些演算法的效能進行分析很重要,這兩類演算法中主要包括二分查詢、快速排序、歸併排序等等。我們先來了解查詢演算法! 順序查詢: 順序查詢又稱線性查詢。它的過程為:從查詢表的最後一個元素開始逐個與給定關鍵字比較,若某個記錄的關鍵字和給定值比較

MIT 線性代數導論 :列空間以及零空間

本講的主要內容: 回顧向量空間以及子空間的知識點 使用線性方程組的思想看待列空間問題 零空間的概念 向量空間以及子空間 這裡主要是對之前的知識的一點回顧,有一點新問題是對於子空間,交以及並是否仍然是子空間? 這裡以三維空間 R3R^{3}R3 為例: 取 P

MIT 線性代數導論 :四個基本子空間

本講的主要內容: 四種子空間的概念以及維數、基 四種基本子空間 首先了解四種基本子空間是什麼: 列空間(column space),簡記為 C(A)C(A)C(A), 由矩陣的列向量生成的空間 零空間(null space),簡記為 N(A)N(A)N(A

資料結構和演算法分析: 五章

散列表的實現常常叫做雜湊。雜湊是一種用於以常數平均時間執行插入、刪除和查詢的技術。 5.1 一般想法 散列表的資料結構是一個包括一些項(item)的具有固定大小的陣列。通常查詢是對於項的某個部分(即資料域)來進行的。這部分就叫做關鍵字。 每個關鍵字被對映到0到T

Java天學習筆記~(集合框架linkedlist、

  LinkedList 內部是連結串列資料結構,是不同步的。增刪元素的速度很快 package day17; import java.util.Iterator; import java.util.LinkedList; public class LinkedList

資料結構學習筆記演算法

一、什麼是雜湊演算法        將任意長度的任意二進位制值串對映為固定長度的二進位制值串,這個對映的規則就是雜湊演算法,而通過原始資料對映之後得到的二進位制值串就是雜湊值。 雜湊演算法需要滿足的要求:

MIT演算法導論公開課之18課 最短路徑演算法、Bellman和差分約束系統

Bellman-Ford 演算法 圖G=(V,E),選取s∈V作為圖的原點,此演算法可計算最短路徑δ(s,v)(v∈V)或報告出圖中存在負權值的環路。 Exercise 在路徑中存在負權值的環路時,將δ(s,v)設定為-∞。 Bellman-F