开放寻址法、链式哈希数据结构详细解读

news/2024/11/13 0:57:37/

一、开放寻址法(Open Addressing)

1. 定义

开放寻址法是一种哈希冲突解决策略,所有元素都存储在哈希表中。当发生冲突时,即两个键计算出的哈希值相同时,会按照一定的探查序列查找下一个可用的位置来存储新元素。

2. 工作原理

开放寻址法中,每个元素都在表内的一个固定位置。探查序列用于寻找下一个可用插入位置,常见的方法包括:

  • 线性探查(Linear Probing):依次检查下一个位置,如 ,其中 i 是步数。
  • 二次探查(Quadratic Probing):检查位置按二次函数递增,如 
  • 双重散列(Double Hashing):使用第二个哈希函数来确定步数,如 ((h(k)+i⋅h′(k))mod  m。
3. 特点
  • 单一存储:所有元素都存储在哈希表内,不需要额外的空间来存储链表或链节点。
  • 探查序列:用于在发生冲突时寻找新的存储位置。
  • 删除标记:删除元素时,通常标记为“已删除”,以避免破坏探查序列。
4. 优缺点
  • 优点

    • 节省空间:不需要额外的结构来存储冲突元素。
    • 简单实现:易于理解和实现。
  • 缺点

    • 负载因子:性能受负载因子的影响,负载因子越大,探查越长,效率越低。
    • 探查冲突:线性探查容易出现聚集问题(大量元素集中在一起)。
    • 删除复杂:删除操作需要特殊标记,处理不当会影响查找效率。
5. 应用场景
  • 内存有限:适合内存有限的场景,不需要额外的存储空间。
  • 中等负载:适用于负载因子较低的情况,以保持性能。
6. 示例代码(Java 实现线性探查)
public class OpenAddressingHashTable {private String[] table;private int size;public OpenAddressingHashTable(int capacity) {this.table = new String[capacity];this.size = 0;}private int hash(String key) {return key.hashCode() % table.length;}public void insert(String key) {int hash = hash(key);int i = 0;while (table[(hash + i) % table.length] != null) {i++;}table[(hash + i) % table.length] = key;size++;}public boolean search(String key) {int hash = hash(key);int i = 0;while (table[(hash + i) % table.length] != null) {if (table[(hash + i) % table.length].equals(key)) {return true;}i++;}return false;}
}

二、链式哈希(Chaining)

1. 定义

链式哈希是一种使用链表来解决哈希冲突的方法。在链式哈希中,每个哈希表的桶(bucket)中存储一个链表。当两个或多个键映射到同一哈希值时,这些键被存储在对应桶的链表中。

2. 工作原理

当元素被插入时,哈希函数计算出其哈希值,并将元素插入到对应桶的链表中。如果桶为空,创建新的链表并将元素加入其中。查找时,哈希值定位桶,然后遍历链表寻找元素。

3. 特点
  • 桶与链表结合:哈希表的每个桶可以存储多个元素,冲突的元素以链表的形式链接。
  • 动态增长:链表的长度不限,可以动态增长以存储任意数量的冲突元素。
  • 负载因子:哈希表性能受负载因子影响,合理的哈希函数和扩展策略有助于保持效率。
4. 优缺点
  • 优点

    • 简单删除:删除操作相对简单,只需从链表中删除节点,不影响整体结构。
    • 负载平衡:对于高负载因子,链表能有效处理大量冲突。
  • 缺点

    • 内存开销:每个链表节点需要额外存储指针,会增加内存消耗。
    • 查找时间:最坏情况下(所有元素哈希到同一个桶),查找时间为 O(n)。
5. 应用场景
  • 动态数据存储:适用于插入和删除频繁的场景。
  • 高负载因子:在负载较高时,链式哈希能更好地维持性能。
6. 示例代码(Java 实现链式哈希)
import java.util.LinkedList;public class ChainingHashTable {private LinkedList<String>[] table;public ChainingHashTable(int capacity) {table = new LinkedList[capacity];for (int i = 0; i < capacity; i++) {table[i] = new LinkedList<>();}}private int hash(String key) {return key.hashCode() % table.length;}public void insert(String key) {int index = hash(key);table[index].add(key);}public boolean search(String key) {int index = hash(key);return table[index].contains(key);}public void delete(String key) {int index = hash(key);table[index].remove(key);}
}

总结比较

方法冲突解决机制操作复杂度优点缺点
开放寻址法探查序列查找空位查找、插入:O(1),最坏:O(n空间效率高,不需要额外结构高负载时性能下降,删除复杂
链式哈希链表存储冲突元素平均:O(1),最坏:O(n)删除简单,负载高时仍保持性能内存开销大,链表操作较慢

http://www.ppmy.cn/news/1546073.html

相关文章

【HarmonyOS】鸿蒙应用低功耗蓝牙BLE的使用心得 (二)

【HarmonyOS】鸿蒙应用低功耗蓝牙BLE的使用心得 &#xff08;二&#xff09; 一、前言 目前鸿蒙应用的实现逻辑&#xff0c;基本都是参考和移植Android端来实现。针对BLE低功耗蓝牙来说&#xff0c;在鸿蒙化的实现过程中。我们发现了&#xff0c;鸿蒙独有的优秀点&#xff0c…

机器学习3_支持向量机_线性不可分——MOOC

线性不可分的情况 如果训练样本是线性不可分的&#xff0c;那么上一节问题的是无解的&#xff0c;即不存在 和 满足上面所有N个限制条件。 对于线性不可分的情况&#xff0c;需要适当放松限制条件&#xff0c;使得问题有解。 放松限制条件的基本思路&#xff1a; 对每个训…

Codeforces Round 984 (Div. 3)

题目链接 A. Quintomania 题意 思路 模拟即可 示例代码 void solve() {int n;cin >> n;vector<int>arr(n);fer(i, 0 ,n) cin >> arr[i];fer(i, 1, n){if(abs(arr[i] - arr[i - 1]) ! 5 && abs(arr[i] - arr[i - 1]) ! 7){cout << "N…

信息安全工程师(78)网络安全应急响应技术与常见工具

前言 网络安全应急响应是指为应对网络安全事件&#xff0c;相关人员或组织机构对网络安全事件进行监测、预警、分析、响应和恢复等工作。 一、网络安全应急响应技术 网络安全应急响应组织 构成&#xff1a;网络安全应急响应组织主要由应急领导组和应急技术支撑组构成。领导组负…

跨界码王:21天从产品汪到攻城狮 | 通义灵码和TA的朋友们

本文转自通义灵码用户分享 我是一名产品汪汪经理&#xff0c;常以满腹需求面对程序猿小哥哥小姐姐的冷眼。我在AI师傅实现了Python入门的从0到1&#xff08;其实是到0.5啦~&#xff09;。 从一个从没写通超过十行代码的编程小白&#xff0c;现在跑通了140行代码实现了自己提的需…

使用 Python 和 OpenCV 实现实时人脸识别

概述 人脸识别是一项重要的计算机视觉任务&#xff0c;广泛应用于安全监控、身份验证等领域。本文将详细介绍如何使用 Python 和 OpenCV 库实现实时人脸识别&#xff0c;并通过具体的代码示例来展示整个过程。 环境准备 在开始编写代码之前&#xff0c;确保已经安装了 OpenC…

PyTorch核心概念:从梯度、计算图到连续性的全面解析(三)

文章目录 Contiguous vs Non-Contiguous TensorTensor and ViewStrides非连续数据结构&#xff1a;Transpose( )在 PyTorch 中检查Contiguous and Non-Contiguous将不连续张量&#xff08;或视图&#xff09;转换为连续张量view() 和 reshape() 之间的区别总结 参考文献 Contig…

GIT GUI和 GIT bash区别

Git GUI 和 Git Bash 都是与 Git 版本控制工具相关的用户界面&#xff0c;但它们有不同的功能和用途。下面详细说明它们的区别及各自的作用&#xff1a; Git GUI 作用&#xff1a; Git GUI 是一个图形用户界面&#xff08;GUI&#xff09;工具&#xff0c;用于执行 Git 操作。…