簡單來講,哈希表是一種依賴哈希函數組織數據,以達到常數級別時間複雜度,插入和搜索都很是高效的數據結構。數組
兩種哈系表:微信
哈希集合
是集合
數據結構的實現之一,用於存儲非重複值
。哈希映射
是映射
數據結構的實現之一,用於存儲(key, value)
鍵值對。大多數高級程序設計語言標準庫裏都內置了哈系表模板。數據結構
哈希表的關鍵思想是使用哈希函數將鍵映射到存儲桶
。更確切地說,函數
在示例中,咱們使用 y = x % 5
做爲哈希函數。讓咱們使用這個例子來完成插入和搜索策略:設計
能夠看得出元素存儲位置與它的關鍵字創建了一個對應關係F,在查找時就能夠由鍵經過哈希函數映射出元素的索引位置(桶),而對應關係F就是哈希散列函數。哈希函數是哈希表中最重要的組件,哈希表用於將鍵映射到特定的桶。上述示例中y = x % 5做爲散列函數,其中
x是鍵值,
y` 是分配的桶的索引。code
散列函數將取決於鍵值的範圍
和桶的數量。
blog
下面是一些哈希函數的示例:索引
哈希函數的設計是一個開放的問題。其思想是儘量將鍵分配到桶中,理想狀況下,完美的哈希函數將是鍵和桶之間的一對一映射。然而,在大多數狀況下,哈希函數並不完美,它須要在桶的數量和桶的容量之間進行權衡。圖片
理想狀況下,若是咱們的哈希函數是完美的一對一映射,咱們將不須要處理衝突。不幸的是,在大多數狀況下,衝突幾乎是不可避免的。例如,在咱們以前的哈希函數(y = x % 5)中,1987 和 2 都分配給了桶 2,這是一個衝突
(因此映射位置稱之爲桶,由於衝突時還須要在桶內做二次查找找到元素的位置)。模板
能夠簡單地使用一個數組將鍵存儲在同一個桶中。若是 N 是可變的或很大,咱們可能須要使用高度平衡的二叉樹
來代替。
若是總共有 M
個鍵,那麼在使用哈希表時,能夠達到 O(M)
的空間複雜度。
而哈希表的時間複雜度與設計有很強的關係。
以使用數組
來將值存儲在同一個桶中爲例,理想狀況下,桶的大小足夠小時,能夠看做是一個常數
。插入和搜索的時間複雜度都是 O(1)
。
但在最壞的狀況下,桶大小的最大值將爲 N
。插入時時間複雜度爲 O(1)
,搜索時爲 O(N)
。
高級程序設計語言內置哈希表的典型設計是:
可哈希化的
類型。而且屬於可哈希類型的值將具備哈希碼
。此哈希碼將用於映射函數以獲取存儲區索引。數組
,用於在初始時將全部值存儲在同一個桶中。高度平衡的二叉樹搜索樹
中。插入和搜索的平均時間複雜度仍爲 O(1)。最壞狀況下插入和搜索的時間複雜度是 O(logN)
,使用高度平衡的 BST。這是在插入和搜索之間的一種權衡。
歡迎關注微信公衆號:愛寫Bug