哈希表(開散列)的實現

目錄

引入

?開散列的底層實現

哈希表的定義

哈希表的擴容

哈希表的插入

哈希表查找

哈希表的刪除


引入

接上一篇,我們使用了閉散列的方法解決了哈希沖突,此篇文章將會使用開散列的方式解決哈希沖突,后面對unordered_set和unordered_map的封裝也會用開散列的哈希表實現。

開散列,也叫哈希桶和拉鏈法,其數組中存儲的不再是單個數據,而是一個個的節點指針。通過將數據映射到對應位置后,插入到鏈表中去。

閉散列就像一個個的鏈表掛在數組上。?


?開散列的底層實現

與閉散列不同的是,開散列哈希表中存儲的是節點,不再是具體數據;也不許需要再存儲狀態,只需要存儲下一個指針即可。

哈希表的定義

template<class K,class V>
struct HashNode
{//默認構造HashNode(const pair<K,V>& kv=pair()):_kv(kv),next(nullptr){ }pair<K, V> _kv;HashNode* _next;
};template<class K,class V>
class HashTable
{typedef HashNode<K, V> Node;
public://默認構造HashTable(){_table.resize(10);  //初始情況下數組有10個空間_n = 0;}private:vector<Node*> _table;size_t _n;   //存儲有效數據
};

哈希表的擴容

開散列在插入時,像閉散列一樣也要檢查載荷因子時候滿足條件。開散列的載荷因子沒有閉散列那么嚴格,開散列的載荷因子要求小于1即可,平均每條鏈有一個數據。

在擴容后也需要對數據進行重新插入。

擴容方法:創建新的哈希表,將原數據的節點一個個的插入到新數組中,再將兩個數組進行交換。

//擴容
void More()
{if ((double)_n / _table.size() >= 1){//進行擴容HashTable newtable;size_t newsize = 2 * _table.size();newtable._table.resize(newsize);  //擴容兩倍擴size_t hashi = 0;while (hashi < _table.size()){if (_table[hashi]){//將數據進行頭插Node* pcur = _table[hashi];while (pcur){Node* next = pcur->_next;pcur->_next = newtable._table[hashi];newtable._table[hashi] = pcur;pcur = next;}}hashi++;}_table.swap(newtable._table);}
}

哈希表的插入

//插入
bool insert(const pair<K, V>& kv)
{//擴容More();size_t hashi = kv.first % _table.size();Node* newnode = new Node(kv);//將數據頭插到對應映射的位置newnode->_next = _table[hashi];_table[hashi] = newnode;_n++;return true;
}

哈希表查找

先找到映射的位置,在對應位置的鏈表中查找。

//查找
bool Find(const K& key)
{size_t hashi = key % _table.size();Node* pcur = _table[hashi];while (pcur){if (pcur->_kv.first == key){return true;}pcur = pcur->_next;}return false;
}

哈希表的刪除

哈希表的刪除比較簡單:直接將該節點的前后指針連起來即可。

//刪除
bool Erase(const K& key)
{size_t hashi = key % _table.size();Node* pcur = _table[hashi];Node* parent = nullptr;while (pcur){if (pcur->_kv.first == key){if (parent == nullptr){delete pcur;pcur = nullptr;_table[hashi] = nullptr;}else{parent->_next = pcur->_next;delete pcur;}return true;}pcur = pcur->_next;}return false;
}

到此,哈希表的開散列的基本實現已經完成。還有一些具體細節將在《哈希表的封裝》中進行具體分析。

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

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

相關文章

機器學習(八):K-Means聚類原理與實戰

聲明&#xff1a;未經允許禁止轉載與抄襲。 前言 k k k均值&#xff08; k k k-means&#xff09;聚類算法是一種經典的無監督聚類算法&#xff0c;本文將深入解析其理論原理&#xff0c;并在真是數據集上進行算法實踐&#xff0c;話不多說&#xff0c;請看下文。 算法原理 …

判斷矩陣A和矩陣B是否相似?

【例題1】 &#xff08;1&#xff09;方法1 &#xff08;2&#xff09;方法2 &#xff08;3&#xff09;方法3 好題\(^o^)/~ 【注意】當二次多項式有重根時&#xff0c;即判別式為零&#xff0c;此時二次多項式是完全平方。

【10】搭建k8s集群系列(二進制部署)之安裝Dashboard和CoreDNS

一、部署Dashboard 1.1、創建kubernetes-dashboard.yaml文件 完整的yaml配置文件信息如下&#xff1a; # Copyright 2017 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in …

大數據技術與Scala

集合高級函數 過濾 通過條件篩選集合元素&#xff0c;返回新集合。 映射 對每個元素應用函數&#xff0c;生成新集集合 扁平化 將嵌套集合展平為單層集合。 扁平化映射 先映射后展平&#xff0c;常用于拆分字符串。 分組 按規則將元素分組為Map結構。 歸約 …

數據驅動可視化實戰:圖表狐精準生成圖表的完整數據范式

一、數據輸入黃金法則 圖表狐 - AI圖表生成工具,在線數據可視化要求數據描述必須包含三個核心要素&#xff1a; [主體對象] [量化指標] [維度劃分] 錯誤示例 ?&#xff1a; "展示各部門銷售額對比" 正確示例 ?&#xff1a; "2023年Q1-Q4各部門銷售額&a…

蒼穹外賣(1)-部分環境配置(git、數據庫)

首先配置git 創建好本地倉庫之后 把項目弄到遠程倉庫里去 先進行提交 &#xff0c;后進行推送 &#xff0c;然后gitee創建一個倉庫 把這個url復制好 推送后會出來一個 點擊推送&#xff0c;會讓你輸入gitee賬號密碼&#xff0c;輸入自己的賬號密碼&#xff0c;就可以連接遠程倉…

Ubunut18.04 離線安裝MySQL 5.7.35

一、環境準備 1.1 官方下載MySQL5.7.35 完整包 1.2 上傳包 & 解壓 上傳包名稱是&#xff1a;mysql-server_5.7.35-1ubuntu18.04_amd64.deb-bundle.tar # 切換到上傳目錄 cd /home/MySQL # 解壓&#xff1a; tar -xvf mysql-server_5.7.35-1ubuntu18.04_amd64.deb-bundle…

Linux(CentOS10) gcc編譯

本例子摘自《鳥哥的linux私房菜-基礎學習第四版》 21.3 用make進行宏編譯 書中的代碼在本機器(版本見下&#xff09;編譯出錯&#xff0c;改正代碼后發布此文章&#xff1a; #kernel version: rootlocalhost:~/testmake# uname -a Linux localhost 6.12.0-65.el10.x86_64 #1…

MCP+Blender創建電力塔

MCP&#xff08;Model Context Protocol&#xff09;與Blender的結合是當前AI與3D建模領域的熱門技術&#xff0c;它通過協議化的方式讓Claude等AI模型直接控制Blender&#xff0c;實現自動化3D建模。 1. 功能與原理 ? 核心能力&#xff1a;用戶通過自然語言指令&#xff08;…

Qt與C++數據類型轉換

本文深入探討Qt與C中相似但不同的數據類型處理技巧。 一、QString與std::string的相互轉換 1. QString → std::string 方法1&#xff1a;使用toStdString()&#xff08;推薦&#xff09; QString qstr "你好&#xff0c;Qt世界"; std::string str qstr.toStdS…

機器學習+EEG熵進行雙相情感障礙診斷的綜合評估

摘要 雙相情感障礙(BD)是一種常見的精神疾病&#xff0c;特點是躁狂或輕躁狂與抑郁交替發作&#xff0c;其嚴重程度各異&#xff0c;導致準確及時的診斷具有一定的挑戰性。EEG的非線性特征被認為是精神障礙的生物標志物&#xff0c;能夠反映大腦的非線性動態。盡管已有研究證明…

企業應用集成全析:架構、實踐與展望

企業應用集成全析&#xff1a;架構、實踐與展望 一、企業應用集成的基本概念1.1 定義1.2 目標 二、企業應用集成的層次架構2.1 數據集成2.2 應用系統集成2.3 業務流程集成? 三、企業應用集成的關鍵技術3.1 中間件技術3.2 Web 服務技術?3.3 企業服務總線&#xff08;ESB&#…

【STL】list介紹(附與vector的比較)

文章目錄 1.關于list2.使用2.1 list的構造2.2 list 迭代器的使用2.3 list 容量操作2.3.1 size()2.3.2 empty()2.3.3 resize() 2.4 list 元素訪問2.4.1 front()2.4.2 back() 2.5 list 修改操作2.5.1 push_front()2.5.2 pop_front()2.5.3 push_back()2.5.4 pop_back()2.5.5 inser…

【Django】教程-12-柱狀圖

【Django】教程-1-安裝創建項目目錄結構介紹 【Django】教程-2-前端-目錄結構介紹 【Django】教程-3-數據庫相關介紹 【Django】教程-4-一個增刪改查的Demo 【Django】教程-5-ModelForm增刪改查規則校驗【正則鉤子函數】 【Django】教程-6-搜索框-條件查詢前后端 【Django】教程…

SQL:DDL(數據定義語言)和DML(數據操作語言)

目錄 什么是SQL&#xff1f; 1. DDL&#xff08;Data Definition Language&#xff0c;數據定義語言&#xff09; 2. DML&#xff08;Data Manipulation Language&#xff0c;數據操作語言&#xff09; DDL和DML的區別 什么是SQL&#xff1f; SQL&#xff08;Structured …

Chrome 135 版本開發者工具(DevTools)更新內容

Chrome 135 版本開發者工具&#xff08;DevTools&#xff09;更新內容 一、性能&#xff08;Performance&#xff09;面板改進 1. 性能面板中的配置文件和函數調用現已顯示來源和腳本鏈接 Performance > Summary&#xff08;性能 > 概覽&#xff09;選項卡現在會顯示配…

[ctfshow web入門] web23

前置知識 include&#xff1a;包含一個文件&#xff0c;也可以包含一些其他東西&#xff0c;后續用到再解析 substr&#xff1a;對字符串進行切片&#xff0c;第一個參數是字符串&#xff0c;第二第三個參數出從第a個索引開始切n個&#xff0c;索引從0開始計數。 例如&#xf…

vue3 開發電子地圖功能

文章目錄 一、項目背景二、頁面效果三、代碼1.ElectronicMap.vue2.TransferDeskRSSIMap.vue3.Map.js4.src/stores/index.js Vuex存儲屬性 四、注意點本人其他相關文章鏈接 一、項目背景 項目采用&#xff1a;vue3javaArco DesignSpringBootOpenStreetMap 數據的地圖切片服務。…

oracle 存儲體系結構

oracle 存儲體系結構 參考&#xff1a; Logical Storage Structures (oracle.com)

python-leetcode 66.尋找旋轉排序數組中的最小值

題目&#xff1a; 已知一個長度為n的數組&#xff0c;預先按照升序排列&#xff0c;經由1到n次旋轉后&#xff0c;得到輸入數組&#xff0c;例如&#xff0c;原數組 nums [0,1,2,4,5,6,7] 在變化后可能得到&#xff1a; 若旋轉 4 次&#xff0c;則可以得到 [4,5,6,7,0,1,2]若…