当前位置: 首页 > wzjs >正文

学校网站模版杭州知名网站建设

学校网站模版,杭州知名网站建设,公司的网址格式,成都上市的网站建设公司遇到的问题,都有解决方案,希望我的博客能为你提供一点帮助。 一、哈希表概述 1.核心原理 哈希表(hash table),又称散列表,是一种高效的数据结构,用于存储键值对(Key-Value Pairs&…

遇到的问题,都有解决方案,希望我的博客能为你提供一点帮助。

一、哈希表概述

1.核心原理 

哈希表(hash table),又称散列表,是一种高效的数据结构,用于存储键值对(Key-Value Pairs)。​

  • ​数据结构​​:散列表是一个固定大小的数组(TableSize),用于存储键值对(item),其中每个项包含​​关键字(key)​​和关联数据(如字符串、数值等)。
  • ​索引范围​​:表的索引从 0 到 TableSize-1,所有关键字通过散列函数映射到这一范围内。
  • ​哈希函数​​:将任意大小的输入(键)转换为固定范围的索引值(通常为数组下标)(如key=1的下标为0)。理想情况下,哈希函数应满足:
    • ​均匀性​​:键尽可能均匀分布,减少冲突。
    • ​高效性​​:计算速度快。
    • ​确定性​​:同一键始终映射到同一索引。
    • ​理想情况​​:每个关键字映射到唯一单元

比如:输入1得到A的时间复杂度为o(1)(相当于数组下标访问)

 2.哈希表高效的原因

数组链表哈希表
查找元素O(n)O(n)O(1)
添加元素O(1)O(1)O(1)
删除元素O(n)O(n)O(1)

数组

  • 查找元素O(n):数组元素连续存储,查找需遍历数组,最坏情况检查所有 n 个元素,时间复杂度与元素数量正相关。
  • 添加元素O(1):若仅在数组末尾添加(不考虑扩容),直接操作尾位置,时间固定。
  • 删除元素O(n):删除元素后,需将后续元素前移填补空位,移动次数与元素数量 n 相关。

链表

  • 查找元素O(n):链表通过指针连接,元素内存不连续,查找需从表头逐节点遍历,最坏遍历整个链表(n 个节点)。
  • 添加元素O(1):若已知插入位置(如指定节点后),仅修改指针指向,时间固定。
  • 删除元素O(n):删除前需先遍历找到目标节点,再修改指针,遍历过程导致 \(O(n)\) 复杂度。

哈希表

  • 查找 / 添加 / 删除(均为 O(1)):通过哈希函数将键映射到固定位置(桶),理想无冲突时,直接定位元素,操作时间恒定。实际虽可能有冲突(如链地址法处理),但平均复杂度仍接近 O(1)。

3. 哈希表的简单实现

基于数组的哈希表实现: 

#include <iostream>
#include <string>
#include <vector>
using namespace std;
class HashTable {
private:vector<pair<int ,string>> hash_table;const int size=100;public:HashTable(int size) {//初始化哈希表的大小为size个元素,每个元素初始化为空值。hash_table.resize(size);}~HashTable() {// vector会自动释放内存}int hash(int key) {//哈希函数,将键值映射到哈希表的索引。return key % size;}void insert(int key, string value) {//插入键值对到哈希表中(假设无哈希冲突)。int index = hash(key);hash_table[index] = make_pair(key, value); }string search(int key) {//查找键对应的值,如果存在则返回值,否则返回空字符串。int index = hash(key)   ;   if (hash_table[index].first == key) {return hash_table[index].second;} else {return "Not Found";}}void remove(int key) {//删除键值对。int index = hash(key);hash_table[index] = make_pair(0, ""); cout << "删除成功" << endl;}// 打印哈希表void print() {for(auto i:hash_table)if(i.first!=0)cout<<"key:"<<i.first<<"value:"<<i.second<<endl;}
};int main(){HashTable ht(100);ht.insert(12345, "A");ht.insert(12355, "B");ht.insert(12365, "C");ht.insert(12376, "D");ht.insert(12387, "E");cout << ht.search(12345) << endl; // 输出: Aht.remove(12345);cout<<ht.search(12345)<<endl;ht.print();
}

 结果如下:

如何去用python实现呢?

class Pair:"""A key-value pair."""def __init__(self, key, value):self.key = keyself.value = value
class HashTable:"""A hash table that uses chaining to handle collisions."""def __init__(self, capacity=100):"""Initialize the hash table with a given capacity."""self.capacity = capacityself.table :list[Pair|None] = [None] * capacitydef hash_function(self, key):"""Compute the hash value for a given key."""return key % self.capacitydef insert(self, key, value):"""Insert a key-value pair into the hash table."""index = self.hash_function(key)if self.table[index] is None:self.table[index] = Pair(key, value)else:print("Collision!")def search(self, key):"""Search for a value in the hash table using a given key."""index = self.hash_function(key)if self.table[index] is not None and self.table[index].key == key:return self.table[index].valueelse:raise KeyError("Key not found.")def remove(self, key):"""Remove a key-value pair from the hash table using a given key."""index = self.hash_function(key)if self.table[index] is not None and self.table[index].key == key:self.table[index] = Noneelse:raise KeyError("Key not found.")def display(self):"""Display the contents of the hash table."""for i in range(self.capacity):if self.table[i] is not None:print(f"Index {i}: {self.table[i].key} -> {self.table[i].value}")
if __name__ == "__main__":# Create a hash table with a capacity of 100ht = HashTable(100)# Insert some key-value pairs into the hash tableht.insert(12345, "A")ht.insert(12355, "B")ht.insert(12365, "C")ht.insert(12376, "D")ht.insert(12387, "E")# Display the contents of the hash tableht.display()# Search for a value in the hash table using a given keyprint(ht.search(12365))# Remove a key-value pair from the hash table using a given keyht.remove(12365)# Display the contents of the hash table after removing a key-value pairht.display()

输出结果:

4.如果两个KEY映射到同一个数组下标了呢?(哈希冲突)

如图23455与33355均映射到了下标为55的桶内,也就是说一个Value对应了两个Key。该如何去解决这个问题呢?

4.1 哈希表的扩容

如果存放桶的数组足够的大,是不是就可以解决这个问题了呢?

像这样如果数组扩容到156,那么key=33355和key=23455是不是就不会再冲突了

ok,下一个问题:扩容触发的阈值?

4.2扩容触发的条件

4.2.1. 什么时候需要扩容(一个可观测的指标)?​
  • 遇到哈希冲突时就扩容(很不好,只是一种想法)
  • ​负载因子(Load Factor)​​:已存储键值对数量 / 数组容量(类似预防手段)。
    • ​示例​​:数组大小为 10,已存 7 个元素,负载因子为 0.7
  • ​阈值设定​​:当负载因子超过预设阈值(如 0.75)时,哈希冲突概率显著增加,操作效率(插入、查找)可能退化为 O(n)
  • ​扩容目的​​:通过扩大数组容量,降低负载因子,减少哈希冲突。
4.2.2.如何去扩容呢?
​(1) 创建新数组​
  • 新数组大小通常为原数组的 ​​2倍​​(或其他策略,如质数扩容)。
    • ​示例​​:原数组大小为 10,扩容后为 20
​(2) 重新哈希(Rehashing)​
  • 遍历原数组中的所有键值对。
  • ​重新计算哈希值​​:根据新数组大小,重新应用哈希函数 index = hash(key) % new_size
  • ​插入新数组​​:将键值对放入新数组的对应位置(需重新处理冲突)。
​(3) 替换旧数组​
  • 释放旧数组内存,将哈希表的底层数组指向新数组。

 代码实现:(在原代码的基础上加上扩容的逻辑)(仅仅只是演示哦,请不要这样写)

#include <iostream>
#include <string>
#include <vector>
using namespace std;
class HashTable {
private:vector<pair<int ,string>> hash_table;int size;public:HashTable(int size): size(size) {//初始化哈希表的大小为size个元素,每个元素初始化为空值。hash_table.resize(size);}~HashTable() {// vector会自动释放内存}int hash(int key) {//哈希函数,将键值映射到哈希表的索引。return key % size;}void insert(int key, string value) {//插入键值对到哈希表中。// 用负载因子检查扩容条件if (load_factor() >= 0.75) { // 负载因子达到0.75时扩容resize(size * 2); // 扩容为原来的两倍}//有冲突时,扩容。if (hash_table[hash(key)].first != 0) { // 冲突处理resize(hash_table.size()* 10); // 扩容为原来的10倍,如55到155}int index = hash(key);hash_table[index] = make_pair(key, value); }string search(int key) {//查找键对应的值,如果存在则返回值,否则返回空字符串。int index = hash(key)   ;   if (hash_table[index].first == key) {return hash_table[index].second;} else {return "Not Found";}}void remove(int key) {//删除键值对。int index = hash(key);hash_table[index] = make_pair(0, ""); cout << "删除成功" << endl;}// 打印哈希表void print() {for(auto i:hash_table)if(i.first!=0)cout<<"key:"<<i.first<<"value:"<<i.second<<endl;}//扩容函数void resize(int new_size) {vector<pair<int, string>> new_table(new_size); // 创建新的哈希表for (auto& pair : hash_table) { // 遍历旧哈希表if (pair.first != 0) { // 如果该位置有元素  int new_index = hash(pair.first); // 计算新的索引new_table[new_index] = pair; // 将元素插入新的哈希表}}hash_table = new_table; // 替换旧哈希表为新的哈希表setSize(new_size); // 更新哈希表的大小}//计算哈希表的负载因子double load_factor() {int count = 0; // 计数器,用于记录非空元素的个数for (auto& pair : hash_table) { // 遍历哈希表if (pair.first != 0) { // 如果该位置有元素count++; // 计数器加1}}  return static_cast<double>(count) / hash_table.size(); // 返回负载因子}void setSize(int size) { // 设置哈希表的大小this->size = size; // 将哈希表的大小设置为size}int getSize() { // 获取哈希表的大小return hash_table.size(); // 返回哈希表的大小} // 新增的getSize函数,用于获取哈希表的大小,用于测试b};int main(){HashTable ht(100);ht.insert(12345, "A");ht.insert(12355, "B");ht.insert(12365, "C");ht.insert(12376, "D");ht.insert(12387, "E");cout << ht.search(12345) << endl; // 输出: Aht.remove(12345);cout<<ht.search(12345)<<endl;ht.print();ht.insert(33355, "X"); // 插入一个新的键值对cout<<"扩容后的大小为:"<<ht.getSize()<<endl;ht.print(); // 打印哈希表
}

 输出结果:

从结果我们也可以看到,仅仅5个元素竟然扩容到了1000的空间 而且再看扩容步骤,所需要的时间耗费也是极大的。

是否有比较好的方法可以去解决哈希冲突呢?

http://www.dtcms.com/wzjs/564073.html

相关文章:

  • 移动电商网站开发需求文档童装网站建设文案
  • 网站打开404错误怎么解决方法wordpress 手机界面
  • wordpress 删除rss狼雨seo培训
  • 专门做钻石国外网站wordpress 移动端 接口
  • 免费手机网站制作杭州网站建设兼职
  • 公众号和网站成都今天发生的重大新闻
  • 北京网站建设正邦微网站建设制作设计
  • 网站顶端flash网约车资格证
  • 昆明网站建设价位外贸平台运营模式
  • 免费在线代理网站怎么做外贸网站的邮箱签名
  • 数码网站模板电商推广平台
  • 徐州营销网站建设服装设计网站素材
  • 怎么免费发布网站wordpress升级文章编辑
  • 建筑电工证查询网站扬州建设银行网站
  • 做平台网站怎么建设个人博客网站
  • 孝感房产网站建设企业网络设计方案论文
  • php网站开发指导教材 文献扬州外贸网站建设
  • 网站建设设计图软件网站开发费属于研发费用吗
  • 长春专业企业网站建设价格杭州专业网站优化公司
  • 北京南站优化推广网站排名
  • 都有哪些网站易点科技网站建设
  • 网站开发软件启动wordpress图片0x0
  • 自己做的网站竞价好还是单页好安卓网站客户端制作软件
  • 网站源码cmswordpress 点赞分享
  • 昆明做网站vr东莞营销型网站建设
  • 书店网站建设定位及目标用模板搭建的网站备案吗
  • 网站开发的方法有哪些wordpress 编码
  • 如何让新网站快速收录电商平台应该如何推广
  • seo 哪些媒体网站可以发新闻江苏省住房和城乡建设厅 官方网站
  • 西安机场商务宾馆百度做网站检察院门户网站建设工作成效