日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构与算法笔记(十五)—— 散列(哈希表)

發布時間:2025/3/21 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法笔记(十五)—— 散列(哈希表) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、前沿

1.1、直接尋址表

當關鍵字的全域U比較小時,直接尋址是一種簡單而有效的技術。假設某應用要用到一個動態集合,其中每個元素都有一個取自全域U={0,1,…,m-1)的關鍵字,此處m是一個不很大的數。另假設沒有兩個元素具有相同的關鍵字。

為表示動態集合,我們用一個數組(或稱直接尋址表)T[0…m一1],其中每個位置(或稱槽)應全域U中的一個關鍵字。下圖說明這個方法;槽 k 指向集合中一個關鍵字為 k 的元素。如果該集合中沒有關鍵字為 k 的元素,則T[k]=NIL。

用一個直接尋址表T實現動態集合。全域U={0,1,…,9}中的每個關鍵字都對應于表中的一個下標值。由實際關鍵字構成的集合K={2,3,5,8}決定表中哪些槽包含指向元素的指針。其他帶深陰影的槽包含NIL

直接尋址技術缺點:

  • 當域U很大時,需要消耗大量內存,很不實際
  • 如果域U很大而實際出現的key很少,則大量空間被浪費
  • 無法處理關鍵字不是數字的情況

1.2、哈希

直接尋址表:key為k的元素放到k位置上

改進直接尋址表:哈希(Hashing)

  • 構建大小為m的尋址表T
  • key為k的元素放到h(k)位置上
  • h(k)是一個函數,其將域U映射到表T[0,1,…,m-1]

二、哈希表

2.1、概念

哈希表(Hash Table,又稱為散列表),是—種線性表的存儲結構。哈希表由一個直接尋址表和一個哈希函數組成。哈希函數h(k)將元素關鍵字k作為自變量,返回元素的存儲下標。

哈希表一個通過哈希函數來計算數據存儲位置的數據結構,通常支持如下操作:

  • insert(key,value):插入鍵值對(key,value)
  • get(key):如果存在鍵為key的鍵值對則返回其value,否則返回空值
  • delete(key):刪除鍵為key的鍵值對

:假設有一個長度為7的哈希表,哈希函數h(k)=k%7。元素集合{14,22,3,5}的存儲方式如下圖:


2.2、哈希沖突

由于哈希表的大小是有限的,而要存儲的值的總數量是無限的,因此對于任何哈希函數,都會出現兩個不同元素映射到同一個位置上的情況,這種情況叫做哈希沖突。

2.2.1、解決哈希沖突——開放尋址法

開放尋址法:如果哈希函數返回的位置已經有值,則可以向后探查新的位置來存儲這個值

  • 線性探查:如果位置i被占用,則探查i+1, i+2,…
  • 二次探查:如果位置i被占用,則探查i+1^2, i-1^2, i+2^2, i-2^2,…
  • 二度哈希:有n個哈希函數,當使用第1個哈希函數h1發生沖突時,則嘗試使用h2,h3,…

2.2.2、解決哈希沖實——拉鏈法

拉鏈法:哈希表每個位置都連接—個鏈表,當沖突發生時,沖突的元素將被加到該位置鏈表的最后。


2.3、常見哈希函數

除法哈希法

乘法哈希法

全域哈希法


三、哈希表實現(拉鏈法)

鏈表代碼(單鏈表):數據結構與算法筆記(三)—— 鏈表(單鏈表、循環鏈表、雙向鏈表)

class HashTable:def __init__(self,size = 20):self.size = sizeself.T = [SingleLinkList() for i in range(self.size)]def h(self,k):'''哈希函數: 計算數據存儲位置'''return k % self.sizedef insert(self,k):'''插入元素'''i = self.h(k)if self.find(k):print('重復插入!!!')else:self.T[i].append(k)def find(self,k):'''查找元素'''i = self.h(k)return self.T[i].search(k)def travel(self):'''遍歷打印'''for i in range(self.size):print(self.T[i].travel())def remove(self,k):'''刪除元素'''if self.find(k):i = self.h(k)self.T[i].remove(k)if __name__ == '__main__':ht = HashTable()ht.insert(0)ht.insert(1)ht.insert(2)ht.insert(21)ht.travel()ht.remove(2)ht.travel()print(ht.find(2))

四、哈希表的應用

4.1、集合與字典

字典與集合都是通過哈希表來實現的。

例如

a = {'name': 'Alex', 'age': 18, 'gender': 'Man'}

使用哈希表存儲字典,通過哈希函數將字典的鍵映射為下標。
假設:

h('name')=3, h('age')=1, h('gender')=4

則哈希表存儲為

[None,18,None,'Alex','Man']

如果發生哈希沖突,則通過拉鏈法或開發尋址法解決


4.2、md5算法

MD5(Message-Digest Algorithm 5)曾經是密碼學中常用的哈希函數,可以把任意長度的數據映射為128位的哈希值,其曾經包含如下特征:

  • 同樣的消息,其MD5值必定相同;
  • 可以快速計算出任意給定消息的MD5值;
  • 除非暴力的枚舉所有可能的消息,否則不可能從哈希值反推出消息本身;
  • 兩條消息之間即使只有微小的差別,其對應的MD5值也應該是完全不同、完全不相關的;
  • 不能在有意義的時間內人工的構造兩個不同的消息使其具有相同的MD5值。
  • 應用舉例: 文件的哈希值

    算出文件的哈希值,若兩個文件的哈希值相同,則可認為這兩個文件是相同的,因此:

  • 用戶可以利用它來驗證下載的文件是否完整。
  • 云存儲服務商可以利用它來判斷用戶要上傳的文件是否已經存在于服務器上,從而實現秒傳的功能,同時避免存儲過多相同的文件副本。

  • 4.3、SHA2算法

    歷史上MD5和SHA-1曾經是使用最為廣泛的 cryptographic hash function,但是隨著密碼學的發展,這兩個哈希函數的安全性相繼受到了各種挑戰。

    因此現在安全性較重要的場合推薦使用SHA-2等新的更安全的哈希函數。

    SHA-2包含了一系列的哈希函數: SHA-224,SHA- 256,SHA-384,SHA-512,SHA-512/224,SHA- 512/256,其對應的哈希值長度分別為224,256,384 or 512位。

    SHA-2具有和MD5類似的性質(參見MD5算法的特征)。

    應用舉例:
    例如,在比特幣系統中,所有參與者需要共同解決如下問題:對于一個給定的字符串U,給定的國標哈希值H,需要計算出一個字符串V,使得U+V的哈希值與H的差小于一個給定值D。此時,只能通過暴力枚舉V來進行猜測。首先計算出結果的人可獲得一定獎金。而某人首先計算成功的概率與其擁有的計算量成正比,所以其獲得的獎金的期望值與其擁有的計算量成正比。

    總結

    以上是生活随笔為你收集整理的数据结构与算法笔记(十五)—— 散列(哈希表)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。