哈希--哈希桶

哈希桶是哈希表(散列表)中的一個概念,是哈希表數組中的每個元素 ,用于存儲鍵值對數據。它有以下特點和相關要點:

  • 結構與原理:哈希表底層常由數組構成,數組的每個元素即哈希桶。通過哈希函數計算鍵的哈希值,該值作為索引指向對應的哈希桶。比如,用哈希函數Hash(key)=key % 10計算鍵key的哈希值,就能確定其對應的哈希桶位置。
  • 沖突處理:不同鍵經哈希函數計算后可能得到相同哈希值,即哈希沖突。常見的處理方式有:
    • 鏈地址法:也叫開散列法,每個哈希桶維護一個鏈表(或其他可鏈接的數據結構)。沖突發生時,將新鍵值對添加到對應哈希桶的鏈表末尾。例如,多個鍵計算出的哈希值都對應數組的第 3 個位置,這些鍵值對就依次鏈接在該位置的鏈表上。
    • 開放尋址法:不借助額外鏈表,所有鍵值對直接存于哈希表數組。沖突發生時,通過線性探測、二次探測或雙重哈希等方式,在數組中找下一個空閑位置存儲鍵值對。
  • 負載因子與擴容:負載因子 = 填入表中元素的個數 / 散列表的長度,用于衡量哈希表的填充程度。負載因子過高會增加哈希沖突概率,影響性能。當達到預設閾值(如 0.75)時,通常會對哈希表進行擴容,創建更大容量的數組,并重新計算所有鍵的哈希值,將鍵值對遷移到新數組的哈希桶中 。
  • 應用場景:廣泛應用于需要快速查找、插入和刪除數據的場景,如數據庫索引、緩存系統、編程語言中的集合類(如 Java 的HashMap、C++ 的unordered_map) 。像在電商系統中,可使用哈希桶快速查找商品信息;在編譯器中,用于符號表的管理,快速查找變量和函數定義。

哈希桶的實現:

namespace hash_bucket
{template<class K>struct hashFunc{size_t operator()(const K& key){return static_cast<size_t>(key);}};template<>struct hashFunc<string>{size_t operator()(const string& key){size_t hash = 0;for (auto e : key){hash *= 131;hash += e;}return hash;}};template<class K,class V>struct HashNode{HashNode<K, V>* next;pair<K, V> _kv;HashNode() {};HashNode(const pair<K,V>& kv):_kv(kv),next(nullptr){}};template<class K,class V,class Hash=hashFunc<K>>class hashTables{using node = HashNode<K, V>;//typedef HashNode<K, V> node;public:hashTables(){_tables.resize(10);}bool insert(const pair<K, V>& kv){if (find(kv.first)){return false;}//下面是擴容,這里需要注意的是它的負載因子可以達到 1 /*if (_n == _tables.size()){size_t newsize = _tables.size() * 2;hashTables<K, V> newTables;newTables._tables.resize(newsize);for (size_t i = 0; i < _tables.size(); i++){node* cur = _tables[i];while (cur){newTables.insert(cur->_kv);cur = cur->next;}}_tables.swap(newTables._tables);}*///這一段相比較上一段減少了insert調用,減少了開銷!if (_n == _tables.size()){vector<node*> newtables;newtables.resize(_tables.size() * 2);for (size_t i = 0; i < _tables.size(); i++){node* cur = _tables[i];while (cur){node* next = cur->next;size_t hashi = hs(cur->_kv.first) % newtables.size();cur->next = newtables[hashi];newtables[hashi] = cur;cur = next;}_tables[i] = nullptr;}_tables.swap(newtables);}size_t hashi = hs(kv.first) % _tables.size();node* newnode = new node(kv);//頭插newnode->next = _tables[hashi];_tables[hashi] = newnode;//更新頭結點!++_n;}node* find(const K& key){size_t hashi =hs(key) % _tables.size();node* cur = _tables[hashi];while (cur){if (cur->_kv.first == key){return cur;}cur = cur->next;}return nullptr;}bool erase(const K& key){size_t hashi =hs( key) % _tables.size();node* cur = _tables[hashi];node* prev = nullptr;while (cur){/*prev = cur;*/if (cur->_kv.first == key){if (prev==nullptr)//頭刪{_tables[hashi] = cur->next;}else//后續正常刪{prev->next = cur->next;}delete cur;return true;}prev = cur;cur = cur->next;}return false;}~hashTables(){for (size_t i = 0; i < _tables.size(); i++){node* cur = _tables[i];while (cur){node* next = cur->next;delete cur;cur = next;}_tables[i] = nullptr;}}void print(){for (size_t i = 0; i <_tables.size(); i++){node* cur = _tables[i];while (cur){cout << "key: " << cur->_kv.first << "-> " << cur->_kv.second << endl;cur = cur->next;}}}private:vector<node*> _tables;//指針數組size_t _n=0;Hash hs;};
}
void test_hush3()
{hash_bucket::hashTables<int, int> h;int a[] = { 1,2,3,4,5,6,7 };for (auto e : a){h.insert(make_pair(e, e));}h.insert({ 8,8 });h.print();h.erase(8);h.print();
}

頭插的時候:

上面的代碼要注意的是它的擴容,它直接重新申請一個數組鏈表,而不是像開放地址法一樣,進行一個重新搞一個對象,然后在對象的新表里面進行挪動數據了。現在哈希桶的這個擴容方法減少了insert的調用!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73396.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73396.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73396.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux多線程詳解

Linux多線程詳解 一、Linux多線程概念1.1 什么是線程1.2 進程和線程1.3 進程的多個線程共享1.4 進程和線程的關系 二、Linux線程控制2.1 POSIX線程庫2.2 線程創建2.3 獲取線程ID pthread_self2.4 線程等待pthread_join2.5 線程終止2.6 線程棧 && pthread_t2.7 線程的局…

Midscene.js自然語言驅動的網頁自動化全指南

一、概述 網頁自動化在數據抓取、UI 測試和業務流程優化中發揮著重要作用。然而&#xff0c;傳統工具如 Selenium 和 Puppeteer 要求用戶具備編程技能&#xff0c;編寫復雜的選擇器和腳本維護成本高昂。Midscene.js 通過自然語言接口革新了這一領域&#xff0c;用戶只需描述任…

winstart.wsf 病毒清理大作戰

0x00 背景 發現感染了winstart.wsf 病毒如何清理。 0x01 現象 遍歷Users下每個目錄以及C:\和C:\Windows\Temp 2個目錄寫入病毒文件。 C:\Users\Administrator\AppData\Local\Temp\winstart.wsf C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Program…

多路轉接Poll

在之前我們講過select是最古老的多路轉接方案&#xff0c;古老就意味著他不是很方便使用&#xff0c;他需要用戶手動保存fd_set這個位圖結構&#xff0c;來表示讀寫事件的關注與否或者就緒性。 而且由于fd_set的大小是固定的&#xff0c;這就意味著他能管理的套接字文件描述符是…

多層感知機的簡潔實現

《動手學深度學習》-4.3-筆記 import torch from torch import nn from d2l import torch as d2l 導入必要的庫和模塊 net nn.Sequential(nn.Flatten(),nn.Linear(784, 256),nn.ReLU(),nn.Linear(256, 10))def init_weights(m):if type(m) nn.Linear:nn.init.normal_(m.we…

【GoLang】調用llm時提示詞prompt的介紹以及使用方式

介紹 提示詞是一種與大模型交互的對話格式&#xff0c;它以 JSON 格式定義了一個消息列表&#xff08;messages&#xff09;&#xff0c;包含了系統消息和用戶消息。 我們向AI提問時&#xff0c;其實發給AI的都是提示詞&#xff0c;別看我們只是簡單輸入了一句話&#xff0c;…

內核編程十二:打印task_struct中的數據

在Linux內核中&#xff0c;current 是一個宏&#xff0c;用于獲取當前正在執行的進程的 task_struct 結構體指針。current 宏返回一個指向當前正在運行的進程的 task_struct 結構體的指針。通過這個指針&#xff0c;內核代碼可以訪問和修改當前進程的各種屬性和狀態。 打印單個…

區間端點(java)(貪心問題————區間問題)

deepseek給了一種超級簡單的做法 我是真的想不到 貪心的思路是 局部最優——>全局最優 這種我是真的沒有想到&#xff0c;這樣的好處就是后面便利的時候可以通過foreach循環直接便利qu的子元素也就是對應的某一個區間, 將一個二維數組變成一維數組&#xff0c;每一個一維…

Qt事件處理(處理鼠標事件、鍵盤事件、定時器事件、窗口移動和大小變化事件)

事件處理 事件是應用程序內部或者外部產生的事情或者動作的統稱。 在 Qt 中&#xff0c;事件是用一個對象來管理一個事件的。所有的事件對象都繼承自抽象類 QEvent 。事件包括鼠標事件、鍵盤事件等&#xff0c;發出自 Qt 或操作系統本身。 處理事件一般通過重寫相關的 Event 函…

Apache Hive:基于Hadoop的分布式數據倉庫

Apache Hive 是一個基于 Apache Hadoop 構建的開源分布式數據倉庫系統&#xff0c;支持使用 SQL 執行 PB 級大規模數據分析與查詢。 主要功能 Apache Hive 提供的主要功能如下。 HiveServer2 HiveServer2 服務用于支持接收客戶端連接和查詢請求。 HiveServer2 支持多客戶端…

利用 @eslint/eslintrc 實現 ESLint9的適配

深度解析&#xff1a;利用 eslint/eslintrc 實現 ESLint 的高效配置管理 在前端開發領域&#xff0c;代碼質量和一致性是至關重要的。ESLint 作為一款流行的代碼檢查工具&#xff0c;幫助開發者發現代碼中的潛在問題并保持代碼風格的一致性。而隨著項目的復雜度增加和團隊規模…

cfca 申請國密證書流程

之前給某銀行開發項目&#xff0c;需要用到cfca國密雙證證書&#xff0c;證書類型為企業雙證的作為接口加密的密鑰。 因為是第一次對接&#xff0c;其中走了不少的彎路&#xff0c;現將申請的流程發布出來做下記錄 1、需要找到cfca的相關人員進行測試證書的申請 2、大概1天的…

基于Spring Boot的鄉村養老服務管理系統的設計與實現(LW+源碼+講解)

專注于大學生項目實戰開發,講解,畢業答疑輔導&#xff0c;歡迎高校老師/同行前輩交流合作?。 技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;…

數字孿生技術如何為制造業開辟新天地?

1. 數字孿生在制造業的崛起背景 1.1 數字孿生的概念演進 “數字孿生”(Digital Twin)一詞最早由美國密歇根大學Michael Grieves博士在2002年提出,但當時并未稱之為“數字孿生”,而是以“信息鏡像模型”描述數字世界與物理世界的映射關系。直到2010年前后,美軍、NASA等在…

學一個前端 UI 框架,要學些什么內容?

假如你現在要自學 React/Vue 框架&#xff0c;怎么學&#xff1f; 絕大部分同學可能是這樣學的&#xff1a; 直接去看官方文檔&#xff0c;或者是找一些視頻看一遍&#xff0c;學會這個框架的一些基礎語法&#xff0c;特性功能等等參考一些例子上手編寫 demo&#xff0c;簡單…

asp.net core mvc模塊化開發

razor類庫 新建PluginController using Microsoft.AspNetCore.Mvc;namespace RazorClassLibrary1.Controllers {public class PluginController : Controller{public IActionResult Index(){return View();}} }Views下Plugin下新建Index.cshtml {ViewBag.Title "插件頁…

2024年MathorCup數學建模C題物流網絡分揀中心貨量預測及人員排班解題全過程文檔加程序

2024年第十四屆MathorCup高校數學建模挑戰賽 C題 物流網絡分揀中心貨量預測及人員排班 原題再現&#xff1a; 電商物流網絡在訂單履約中由多個環節組成&#xff0c;圖1是一個簡化的物流網絡示意圖。其中&#xff0c;分揀中心作為網絡的中間環節&#xff0c;需要將包按照不同流…

鴻蒙Flutter開發故事:不,你不需要鴻蒙化

在華為牽頭下&#xff0c;Flutter 鴻蒙化如火如荼進行&#xff0c;當第一次看到一份上百個插件的Excel 列表時&#xff0c;我也感到震驚&#xff0c;排名前 100 的插件赫然在列&#xff0c;這無疑是一次大規模的軍團作戰。 然后&#xff0c;參戰團隊魚龍混雜&#xff0c;難免有…

Unity音頻混合器如何暴露參數

音頻混合器是Unity推薦管理音效混音的工具&#xff0c;那么如何使用代碼對它進行管理呢&#xff1f; 首先我在AudioMixer的Master組中創建了BGM和SFX的分組&#xff0c;你也可以直接用Master沒有問題。 這里我以BGM為例&#xff0c;如果要在代碼中進行使用就需要將參數暴露出去…

Vue項目與云管平臺Nginx部署筆記

Vue項目與云管平臺Nginx部署筆記 一、項目架構說明 footAdmin云管前端 Vue2 Webpack 構建&#xff0c;部署路徑&#xff1a;/usr/share/nginx/html/footAdmin 使用npm run build生成/dist目錄&#xff0c;然后將dist目錄下面的所有文件&#xff0c;上傳到虛擬機/usr/share/n…