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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【Java】 大话数据结构(13) 查找算法(4) (散列表(哈希表))

發布時間:2025/3/15 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java】 大话数据结构(13) 查找算法(4) (散列表(哈希表)) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文根據《大話數據結構》一書,實現了Java版的一個簡單的散列表(哈希表)

基本概念

對關鍵字key,將其值存放在f(key)的存儲位置上。由此,在查找時不需比較,只需計算出f(key)便可直接取得所查記錄。這個函數 f() 就叫做散列函數,按這個思想建立的表稱為散列表。

散列技術即是一種存儲方法,又是一種查找方法:

  存儲過程:根據關鍵字key,算出f(key),將記錄存放在f(key)的位置上;

  查找過程:根據關鍵字key,算出f(key),該位置上的值即為要找的記錄。

?

散列函數的構造方法

直接定址法

直接取關鍵字的線性函數為散列地址:f(key)=a×key+b(a,b為常數)

如:對下表的記錄,關鍵字key取為出生年份,令f(key)=key-1980即可。

數字分析法

分析一組數據,找出其規律,盡可能利用這些數據來構造沖突幾率較低的散列地址

如:以員工的手機號碼作為關鍵字,前7位數字基本相同,可以選擇后面四位數字作為散列地址。

平方取中法

當無法確定關鍵字中哪幾位分布較均勻時,可以先求出關鍵字的平方值,然后按需要取平方值的中間幾位作為散列地址。

折疊法

將關鍵字分割成位數相同的幾部分,最后一部分位數可以不同,然后取這幾部分的疊加和(去除進位)作為散列地址。

除留余數法

最為常用的方法,取關鍵字被某個不大于散列表表長m的數p除后所得的余數為散列地址。

f(key) = key MOD p,p<=m。

隨機數法

?選擇一隨機函數(偽隨機),取關鍵字的隨機值作為散列地址,通常用于關鍵字長度不同的場合。

?

處理散列沖突的方法

當兩個關鍵字key1和key2不同時,有f(key1)=f(key2),這種現象稱為沖突。一般情況下,我們會盡量設計恰當的散列函數減少沖突,但無法完全避免,這就需要對沖突進行處理。

開放尋址法

一旦發生沖突,就去尋找下一個空的散列地址,只要散列表足夠大,空的散列地址總能找到,并將記錄存入。根據下一個位置的不同,又可分為以下三種:

①線性探測法:

②二次探測法

③隨機探測法

再散列函數法

在同義詞產生地址沖突時計算另一個散列函數地址,直到沖突不再發生,這種方法不易產生“聚集”,但增加了計算時間。如下圖所示(RHi代表不同的散列函數):

?

鏈地址法

相同地址的記錄存放在一個單鏈表中,散列表值存儲所有同義詞子表的頭指針。如下圖所示:

公共溢出區法

為所有沖突的關鍵字建立一個公共的溢出區來存放。

?

代碼實現

接下來建立一個簡單的散列表,其散列函數采用上述的除留余數法,處理沖突的方法采用開放定址法下的線性探測法。

Java代碼如下:

package HashTable;/*** 散列表* @author Yongh**/ public class HashTable {int[] elem;int count;private static final int Nullkey = -32768;public HashTable(int count) {this.count = count;elem = new int[count];for (int i = 0; i < count; i++) {elem[i] = Nullkey; // 代表位置為空}}/** 散列函數*/public int hash(int key) {return key % count; // 除留余數法}/** 插入操作*/public void insert(int key) {int addr = hash(key); // 求散列地址while (elem[addr] != Nullkey) { // 位置非空,有沖突addr = (addr + 1) % count; // 開放地址法的線性探測}elem[addr] = key;}/** 查找操作*/public boolean search(int key) {int addr = hash(key); // 求散列地址while (elem[addr] != key) {addr = (addr + 1) % count; // 開放地址法的線性探測if (addr == hash(key) || elem[addr] == Nullkey) { // 循環回到原點或者到了空地址System.out.println("要查找的記錄不存在!");return false;}}System.out.println("存在記錄:" + key + ",位置為:" + addr);return true;}public static void main(String[] args) {int[] arr = { 12, 67, 56, 16, 25, 37, 22, 29, 15, 47, 48, 34 };HashTable aTable = new HashTable(arr.length);for (int a : arr) {aTable.insert(a);}for (int a : arr) {aTable.search(a);}} }

  

存在記錄:12,位置為:0 存在記錄:67,位置為:7 存在記錄:56,位置為:8 存在記錄:16,位置為:4 存在記錄:25,位置為:1 存在記錄:37,位置為:2 存在記錄:22,位置為:10 存在記錄:29,位置為:5 存在記錄:15,位置為:3 存在記錄:47,位置為:11 存在記錄:48,位置為:6 存在記錄:34,位置為:9 HashTable

  代碼中重點可以看:插入操作是如何處理沖突 以及查找操作是如何判斷記錄是否存在的。

?

轉載于:https://www.cnblogs.com/yongh/p/9284896.html

總結

以上是生活随笔為你收集整理的【Java】 大话数据结构(13) 查找算法(4) (散列表(哈希表))的全部內容,希望文章能夠幫你解決所遇到的問題。

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