哈希表(Hash Table)

概覽:

​ 簡單來講,哈希表是一種依賴哈希函數組織數據,以達到常數級別時間複雜度,插入和搜索都很是高效的數據結構。數組

兩種哈系表:微信

  • 哈希集合集合數據結構的實現之一,用於存儲非重複值
  • 哈希映射映射 數據結構的實現之一,用於存儲(key, value)鍵值對。

大多數高級程序設計語言標準庫裏都內置了哈系表模板。數據結構

一、哈希表的原理


哈希表的關鍵思想是使用哈希函數將鍵映射到存儲桶。更確切地說,函數

  1. 當咱們插入一個新的鍵時,哈希函數將決定該鍵應該分配到哪一個桶中,並將該鍵存儲在相應的桶中;
  2. 當咱們想要搜索一個鍵時,哈希表將使用相同的哈希函數來查找對應的桶,並只在特定的桶中進行搜索。

示例


img

在示例中,咱們使用 y = x % 5 做爲哈希函數。讓咱們使用這個例子來完成插入和搜索策略:設計

  1. 插入:咱們經過哈希函數解析鍵,將它們映射到相應的桶中。
    • 例如,1987 分配給桶 2,而 24 分配給桶 4。
  2. 搜索:咱們經過相同的哈希函數解析鍵,並僅在特定存儲桶中搜索。
    • 若是咱們搜索 1987,咱們將使用相同的哈希函數將1987 映射到 2。所以咱們在桶 2 中搜索,咱們在那個桶中成功找到了 1987。
    • 例如,若是咱們搜索 23,將映射 23 到 3,並在桶 3 中搜索。咱們發現 23 不在桶 3 中,這意味着 23 不在哈希表中。

哈希散列函數:

​ 能夠看得出元素存儲位置與它的關鍵字創建了一個對應關係F,在查找時就能夠由鍵經過哈希函數映射出元素的索引位置(桶),而對應關係F就是哈希散列函數。哈希函數是哈希表中最重要的組件,哈希表用於將鍵映射到特定的桶。上述示例中y = x % 5做爲散列函數,其中x是鍵值,y` 是分配的桶的索引。code

​ 散列函數將取決於鍵值的範圍桶的數量。blog

下面是一些哈希函數的示例:索引

img

​ 哈希函數的設計是一個開放的問題。其思想是儘量將鍵分配到桶中,理想狀況下,完美的哈希函數將是鍵和桶之間的一對一映射。然而,在大多數狀況下,哈希函數並不完美,它須要在桶的數量和桶的容量之間進行權衡。圖片

二、衝突解決


理想狀況下,若是咱們的哈希函數是完美的一對一映射,咱們將不須要處理衝突。不幸的是,在大多數狀況下,衝突幾乎是不可避免的。例如,在咱們以前的哈希函數(y = x % 5)中,1987 和 2 都分配給了桶 2,這是一個衝突(因此映射位置稱之爲桶,由於衝突時還須要在桶內做二次查找找到元素的位置)。模板

​ 能夠簡單地使用一個數組將鍵存儲在同一個桶中。若是 N 是可變的或很大,咱們可能須要使用高度平衡的二叉樹來代替。

三、複雜度分析


若是總共有 M 個鍵,那麼在使用哈希表時,能夠達到 O(M) 的空間複雜度。

而哈希表的時間複雜度與設計有很強的關係。

以使用數組來將值存儲在同一個桶中爲例,理想狀況下,桶的大小足夠小時,能夠看做是一個常數。插入和搜索的時間複雜度都是 O(1)

但在最壞的狀況下,桶大小的最大值將爲 N。插入時時間複雜度爲 O(1),搜索時爲 O(N)

內置哈希表的原理


高級程序設計語言內置哈希表的典型設計是:

  1. 鍵值能夠是任何可哈希化的類型。而且屬於可哈希類型的值將具備哈希碼。此哈希碼將用於映射函數以獲取存儲區索引。
  2. 每一個桶包含一個數組,用於在初始時將全部值存儲在同一個桶中。
  3. 若是在同一個桶中有太多的值,這些值將被保留在一個高度平衡的二叉樹搜索樹中。

插入和搜索的平均時間複雜度仍爲 O(1)。最壞狀況下插入和搜索的時間複雜度是 O(logN),使用高度平衡的 BST。這是在插入和搜索之間的一種權衡。

在這裏插入圖片描述 歡迎關注微信公衆號:愛寫Bug

相關文章
相關標籤/搜索