1. 程式人生 > >java中的資料結構——雜湊表

java中的資料結構——雜湊表

雜湊表

雜湊法是一個用於唯一標識物件並將每個物件儲存在一些預先計算的唯一索引(鍵)中的過程,因此, 物件以鍵值對的形式儲存,鍵值對的集合稱為字典,可以使用鍵搜尋每個物件。雜湊法有很多不同的數 據結構,但最常用的是雜湊表。 雜湊表通常使用陣列實現,它可以提供快速的查詢和插入操作,雜湊表不僅速度快(比樹快),程式設計實 現也相對容易。
缺點:基於陣列,陣列建立後難以擴充套件,某些雜湊表被基本填滿時,效能下降的非常嚴重,所以必須要 清楚表中要儲存多少資料,而且,也沒有一種簡便的方法可以以任何一種順序遍歷表中資料項。 如果不需要有序遍歷資料,並且可以提前預測資料量的大小,那麼雜湊表在速度和易用性方面都很好。

雜湊資料結構的效能取決於以下三個因素。雜湊函式,雜湊表的大小,碰撞處理方法。
如何把關鍵字轉換成陣列下標? 在雜湊表中,這個轉換通過雜湊函式來完成,對於特定的關鍵字,並不需要雜湊函式,關鍵字的值可以 直接用於陣列下標(關鍵字作為索引)。使用基於陣列的資料庫,會使得儲存資料速度快且非常簡單。
若關鍵字不能恰好用於陣列下標時,如何使用雜湊函式進行轉換? 字典 在一些計算機語言的編譯器中,通常用雜湊表保留符號表(記錄遍歷和函式名及記憶體中的地址)。
效率: 不論雜湊表中有多少資料,插入和刪除只需要接近常量的時間,即O(1)的時間級,實際上,這隻需要幾 條機器指令。
擴充套件陣列: 當雜湊表變得太滿時,就需要擴充套件陣列。

在java中,陣列有固定的大小,而且不能擴充套件,程式設計時只能另 外建立一個新的更大的陣列,然後把舊陣列的所有內容插入到新的陣列中。雜湊函式根據陣列大小計算 給定資料項的位置,所以這些資料項不能在放到新陣列中和老陣列相同的位置上。因此,不能簡單的從 一個數組向另一個數組拷貝資料,需要按順序遍歷老陣列,用insert方法向新陣列中插入每個資料項, 這就是重新雜湊化,這是一個耗時的過程,但是如果陣列一定要進行擴充套件,那麼就必須進行這個過程。 擴充套件後的陣列容量通常是原來的兩倍。

雜湊函式: 好的雜湊函式很簡單,所以它能快速計算。雜湊表的主要優點是它的速度,如果雜湊函式執行緩慢,速 度就會降低,雜湊函式中有很多乘法和除法是不可取的。雜湊函式的目的是得到關鍵字值的範圍,把它 用一種方式轉化成陣列的下標值,這種方法應該使關鍵字值隨機的分佈在整個雜湊表中。關鍵字可能隨 機,也可能不隨機。
雜湊化和外部儲存 磁碟由許多包含檔案的塊組成,存取一個塊的時間比任何在記憶體中存取資料的時間都要長的多,因此, 在設計外部儲存策略時,不考慮最小化存取塊的數量。而且,外部儲存器單位容量很便宜,所以,可以 使用更大數量的儲存器,超過要存取的項數,如果這樣,會加快存取時間,這就有可能使用雜湊表。 檔案指標表 外部雜湊化的關鍵部分是一個雜湊表,它包含塊成員,指向外部儲存器中的塊。雜湊表有時叫做索引, 它可以儲存在記憶體中,如果太大,也可以儲存在磁碟上,而把它的一部分放在記憶體中,即使把雜湊表都放在記憶體中,也要在磁碟儲存一個備份,檔案開啟時,把它存入記憶體。 未填滿塊 在外部雜湊化中,重要的是塊不要填滿。所有關鍵字對映為同一個值的記錄都定位到相同塊。為找到特 定關鍵字的一個記錄,搜尋演算法雜湊化關鍵字,用雜湊值作為雜湊表的下標,得到某個下標中的塊號, 然後讀取這個塊。定位一個特定的資料項,只需要訪問一次塊。缺點是很多的磁碟空間被浪費了,因為 設計時規定,塊是不允許填滿的。所以必須仔細選擇雜湊函式和雜湊表的大小,為的是限制對映到相同 的值關鍵字的數量。 填滿的塊 即使用一個好的雜湊函式,塊偶爾也會填滿。這時,可以使用在內部雜湊表中處理衝突的不同方法:開 放地址法和鏈地址法。
開放地址法

:插入時,如果發現一個塊是滿的,演算法在相鄰的塊插入新記錄,線上性探測中,這是下一 個塊,但也可以用二次探測或再雜湊法選擇。 在鏈地址法中,有一個溢位塊,當發現塊已滿時,新記錄插在溢位塊中。 填滿的塊是不合乎需要的,因為有了它就需要額外的磁碟訪問,這就需要兩倍的訪問時間,如果這種情 況不經常發生也可以忽略。

上一篇:java中的資料結構——佇列
下一篇:java中的資料結構——連結串列