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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hashmap赋值给另一个hashmap_图解设计一个 HashMap

發(fā)布時(shí)間:2025/3/20 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hashmap赋值给另一个hashmap_图解设计一个 HashMap 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目前我們學(xué)到的數(shù)據(jù)結(jié)構(gòu)有:單鏈表,雙向鏈表,棧,隊(duì)列,循環(huán)隊(duì)列,雙端隊(duì)列。今天學(xué)習(xí) LeetCode 的 「 706. Design HashMap 」,從設(shè)計(jì)一個(gè) HashMap 到掌握其內(nèi)部原理。題目要求:

Design a HashMap without using any built-in hash table libraries.
To be specific, your design should include these functions:put(key, value) : Insert a (key, value) pair into the HashMap. If the value already exists in the HashMap, update the value.get(key): Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key.remove(key) : Remove the mapping for the value key if this map contains the mapping for the key.

? All keys and values will be in the range of [0, 1000000].

The number of operations will be in the range of?[1, 10000].

題目要求設(shè)計(jì)一個(gè) HashMap,不能使用語言提供的類似哈希表的庫,比如HashMap,dict,map,需要實(shí)現(xiàn)下面幾個(gè)方法:

1. put(key, value) : 根據(jù) key 插入一個(gè) value,如果 key 已經(jīng)存在,更新 value;

2. get(key): 根據(jù)一個(gè) key 獲取對應(yīng)的值,如果未找到對應(yīng)的 value,返回 -1;

3. remove(key) : 根據(jù) key 來刪除對應(yīng)的值。

分析

HashMap 是一種典型的以空間換取時(shí)間的數(shù)據(jù)結(jié)構(gòu),在設(shè)計(jì)緩存算法 LRU 和 LFU 當(dāng)中用到了 C++ 提供的 unorder_map,利用HashMap 的特點(diǎn),做到存取時(shí)間復(fù)雜度為 O(1) 。今天我們要掌握如何設(shè)計(jì)一個(gè) HashMap。設(shè)計(jì)之前需要知道?HashMap 是一種什么樣的數(shù)據(jù)結(jié)構(gòu)?

HashMap 的核心思想是 「 把 key 通過一種方式轉(zhuǎn)換成一個(gè) hashCode(一個(gè)整形數(shù)),通過 hashCode 來存取對應(yīng)的 value 」,轉(zhuǎn)換的方式就是哈希函數(shù),在轉(zhuǎn)換的過程中,不同的 key 可能會生成同一 hashCode,這將產(chǎn)生「哈希沖突」。

一圖勝千言!

插入 key 對應(yīng)的 value 函數(shù)為:put(key, value):

執(zhí)行 put(1, 1),1 的 hash 值 hash(1) = 1 % 5 = 1,放到 1 個(gè)位置;

執(zhí)行 put(4, 4),4 的 hash 值 hash(4) = 4 % 5 = 4,放到 4 個(gè)位置;

執(zhí)行 put(6, 6),6 的 hash 值 hash(6) = 6 % 5 = 1,放到 1 個(gè)位置,第一個(gè)位置已經(jīng)存放了 1,產(chǎn)生「哈希沖突」;

綜上,設(shè)計(jì)一個(gè)哈希表需要做下面 2 件事:

1.設(shè)計(jì)哈希函數(shù);

衡量一個(gè)哈希函數(shù)設(shè)計(jì)的好壞是看它是否能夠讓 value 「均勻分布」,也就是產(chǎn)生哈希沖突越少越好。語言本身一般會提供計(jì)算 hashCode 的方法,比如 OC 中的 NSObject 類提供了 hash 方法:

NSString *name = @"Lefe_x";NSString?*des?=?@"超越技術(shù)公眾號做圖解算法";NSLog(@"hash(name)?=?%@,?hash(des)=%@",?@(name.hash),?@(des.hash));// hash(name) = 7306077673678745, hash(des)=7723704617483326955

2.解決哈希沖突;

不同的 key 生成的 hashCode 相同就產(chǎn)生了哈希沖突,解決沖突有主要有下面幾種方式:

鏈地址法:產(chǎn)生哈希沖突后,把產(chǎn)生沖突的元素使用某種方式「組合」到一起,可以使用鏈表、紅黑樹,或者使用其它數(shù)據(jù)結(jié)構(gòu)。

把 1、6、3、4、13 分別 put 到哈希表中,1、6、13 的哈希值均為 1,被放到第一個(gè)位置,可以通過鏈表、紅黑樹進(jìn)行存儲。

開地址法:產(chǎn)生哈希沖突后,把 value 放到其它空閑位置,可以使用線性探測法放到下一個(gè)空閑位置;使用平方探測法,放到第1個(gè)、第 4個(gè)、第9個(gè)、第16個(gè)......空閑位置;使用二次哈希,通過另外一個(gè)哈希函數(shù)再計(jì)算一次哈希值。

使用線性探測法解決沖突,把 1、6、3、4、13 分別 put 到哈希表中,1、6、13 的哈希值均為 1,會產(chǎn)生沖突,當(dāng)遇到?jīng)_突后,把 value 插入到下一個(gè)位置。保存結(jié)果如下圖:

代碼

通過上面的分析可知,實(shí)現(xiàn)一個(gè) HashMap,需要一個(gè)實(shí)現(xiàn)一個(gè)哈希函數(shù)和解決哈希沖突,代碼中通過「鏈地址法」來解決哈希沖突。題目中的 key 和 value 的取值范圍為 [ 0 - 1000000 ]。代碼原理如圖:

C++ 代碼如下(來源于 LeetCode):

#include #include #include using?namespace?std;class MyHashMap { size_t m_size = 10000; vector<listint, public: // 初始化,設(shè)置大小 MyHashMap() { m_data.resize(m_size); } // 哈希函數(shù) int hashCode(int key) { return key % m_size; } // 根據(jù) key 存儲對應(yīng)的 value,如果 key 已經(jīng)存在,更新 value void put(int key, int value) { // 根據(jù)哈希函數(shù)找到對應(yīng)的鏈表 auto &list = m_data[hashCode(key)]; for (auto & val : list) { // 如果已經(jīng)存在,根據(jù) key 來更新對應(yīng)的值 if (val.first == key) { val.second = value; return; } } // 插入鏈表的尾部 list.emplace_back(key, value); } // 根據(jù) key 來獲取值 int get(int key) { const auto &list = m_data[hashCode(key)]; if (list.empty()) { return -1; } for (auto & val : list) { // 如果已經(jīng)存在,找到了對應(yīng)的值 if (val.first == key) { return val.second; } } return -1; } // 根據(jù) key 刪除對應(yīng)的值 void remove(int key) { auto &list = m_data[hashCode(key)]; // 找到節(jié)點(diǎn)后刪除 list.remove_if([key](auto n) { return n.first == key; }); }};

總結(jié)

至此,一個(gè)簡單的 HashMap 就完成了,如果設(shè)計(jì)一個(gè)復(fù)雜的 HashMap,需要考慮數(shù)據(jù)達(dá)到一定程度后,需要對 vector 進(jìn)行擴(kuò)容、縮容處理,如果沖突達(dá)到某一個(gè)量級后,需要考慮更換 list 這個(gè)數(shù)據(jù)結(jié)構(gòu),比如換成紅黑樹。

推薦閱讀:

論證:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法很重要

圖解 LFU cache

圖解數(shù)據(jù)結(jié)構(gòu)和算法

總結(jié)

以上是生活随笔為你收集整理的hashmap赋值给另一个hashmap_图解设计一个 HashMap的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩欧美网 | 一级特黄录像免费看 | 少妇熟女高潮流白浆 | 伊人久久视频 | 成年人毛片 | 午夜网| 丁香久久综合 | 国产资源在线视频 | 误杀1电影免费观看高清完整版 | 天天操天天干天天爽 | 日韩亚州 | 亚洲美女屁股眼交 | 国产精品视频123 | 黄色综合网站 | 日韩一区二区在线观看 | 欧美一区二区日韩一区二区 | 欧洲女同同性吃奶 | 国产精品女人精品久久久天天 | 一区二区精品视频 | 男同av在线观看一区二区三区 | 夜间福利在线观看 | 无码精品人妻一二三区红粉影视 | 免费观看一区二区三区毛片 | 久久久久久蜜桃 | 女女爱爱视频 | 美国一区二区 | 国产精品啪啪啪视频 | 日韩一区不卡 | 成人免费在线网址 | 欧美激情视频网站 | 国产无玛 | 黄色网页在线 | 在线观看成人黄色 | 七仙女欲春2一级裸体片 | 国产精品一区二区无码对白 | 午夜电影一区二区三区 | av毛片在线播放 | 97久久国产 | 国产精品无码一区二区三区 | 精品国产乱码久久久久夜深人妻 | 91极品视频| 亚洲风情亚aⅴ在线发布 | 亚洲欧洲中文 | 欧美 日韩 国产 成人 在线观看 | 国产欧美一区二区三区鸳鸯浴 | 青青草成人免费视频 | 波多野结衣在线免费观看视频 | 色xxxxx| 亚洲国产日韩a在线播放性色 | 99视频网址 | 久久亚洲精品视频 | 黄色片网站在线观看 | 国产精品偷乱一区二区三区 | 福利综合网 | 九七影院在线观看免费观看电视 | 老头吃奶性行交 | 国产无遮挡又黄又爽在线观看 | av不卡网站 | 国产日韩欧美高清 | 草草视频网站 | 天天射天天草 | 尤物在线观看 | 美女扒开腿让男人 | 日本美女黄色大片 | 成人中文字幕在线 | 穿越异世荒淫h啪肉np文 | 一级片久久 | 精品一二三四区 | 国产ts变态重口人妖hd | 久久久久久国产精品一区 | 欧洲美女与动交ccoo | 97看片吧| 日本免费无人高清 | 免费av网址在线观看 | 欧美一级爽aaaaa大片 | 国产精品久久久免费观看 | 91超碰在线播放 | 神马午夜一区二区 | 日本伦理片在线看 | 国产精品久久久久野外 | 久久国内视频 | 国产高潮国产高潮久久久 | 性欧美video另类hd尤物 | 91精品国产91久久久久 | 视频这里只有精品 | 欧美乱三级 | 日韩网站免费观看 | 国产一区2区 | 中文字幕在线二区 | 免费aa视频| 国产理论| 亚洲成人黄色影院 | 天堂视频在线免费观看 | 亚洲国产精品无码观看久久 | 可以免费观看的av网站 | 美女大黄动图 | 五月天激情国产综合婷婷婷 | 捆绑无遮挡打光屁股 | 精品免费国产一区二区三区四区 |