HashTable(哈希表分离链接法)

2024-08-25 08:18
文章标签 分离 哈希 链接 hashtable

本文主要是介绍HashTable(哈希表分离链接法),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

哈希表的分离链接法其实就是个vector<type>容器 + 链表来实现的,其本质就是如果数值(mod)相等的话就插入到vector<type>的同一格,将相等的两个值依次存放在链表中,如果空间很小的话建议不要采用此方法,因为此方法的链表为双向链表,下面为分离链接法的代码:
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<list>
using namespace std;
template<typename HashedObj>
class HashTable
{
public:explicit HashTable(int size = 101){theLists.resize(size);currentSize = size;}bool contains(const HashedObj & x) const;void makeEmpty();bool insert(const HashedObj & x);bool remove(const HashedObj & x);
private:vector<list<HashedObj> > theLists; // the array of Listsint currentSize;void rehash();int myHash(const HashedObj &x) const;
};
class Employee
{
public:const string &getName() const{return name;}bool operator== (const Employee &rhs) const{return getName() == rhs.getName();}bool operator!= (const Employee &rhs) const{return !(*this == rhs);}
private:string name;double salary;int senioity;
};
int hash(const string & key)
{int hashVal = 0;for(int i=0;i<key.length();i++){hashVal = hashVal * 37 + key[i];}return hashVal;
}
int hash(int key)
{return key;
}
int hash(const Employee & item)
{return hash(item.getName());
}
bool Prime(int res)         //散列表最好为素数
{for(int i=2;i<res/2;i++){if(res % i == 0){return true;break;}}return false;
}
int nextPrime(int num)
{while(1){if(Prime(num) == false){return num;break;}else{num++;}}
}
template<typename HashedObj>
int HashTable<HashedObj>::myHash(const HashedObj & x) const
{int hashVal = hash(x);hashVal %= theLists.size();  //theLists.size()为总容量if(hashVal < 0){hashVal += theLists.size();}return hashVal;
}
template<typename HashedObj>
void HashTable<HashedObj>::rehash()
{vector<list<HashedObj> > oldLists = theLists;theLists.resize(nextPrime(2 * theLists.size()));for(int j=0;j<theLists.size();j++){theLists[j].clear();}cout<<theLists.size()<<endl;currentSize = 0;for(int i=0;i<oldLists.size();i++)  //vector<>从上到下{typename list<HashedObj>::iterator itr = oldLists[i].begin(); //链表头到尾覆盖while(itr != oldLists[i].end())insert(*itr++);}
}
template<typename HashedObj>
void HashTable<HashedObj>::makeEmpty()
{for(int i=0;i<theLists.size();i++){theLists[i].clear();}
}
template<typename HashedObj>
bool HashTable<HashedObj>::contains(const HashedObj & x) const
{const list<HashedObj> &whichList = theLists[myHash(x)];return find(whichList.begin(),whichList.end(),x) != whichList.end();
}
template<typename HashedObj>
bool HashTable<HashedObj>::remove(const HashedObj &x)
{list<HashedObj> & whichList = theLists[myHash(x)];typename list<HashedObj>::iterator itr = find(whichList.begin(),whichList.end(),x);if(itr == whichList.end()){return false;}whichList.erase(itr);--currentSize;return true;
}
template<typename HashedObj>
bool HashTable<HashedObj>::insert(const HashedObj &x)
{list<HashedObj> & whichList = theLists[myHash(x)];if(find(whichList.begin(),whichList.end(),x) != whichList.end()){return false; // 如果已经存在}whichList.push_back(x);if(++currentSize >theLists.size())rehash();return true;
}
int main()
{HashTable<int> b;b.insert(1);b.insert(10);b.insert(100);b.insert(9);b.insert(69);b.insert(57);if(b.contains(100) && b.contains(57)){cout<<"yes"<<endl;}else{cout<<"no"<<endl;}if(b.insert(57)){cout<<"insert succeed!"<<endl;}else{cout<<"repeat!"<<endl;}if(b.remove(69)){cout<<"remove succeed!"<<endl;}else{cout<<"The element not exist in HashTable";}b.makeEmpty();if(b.contains(1) || b.contains(10) || b.contains(100)){cout<<"The HashTable is not empty!"<<endl;}else{cout<<"It is empty!"<<endl;}return 0;
}



这篇关于HashTable(哈希表分离链接法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1105027

相关文章

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

Spring Security 前后端分离场景下的会话并发管理

《SpringSecurity前后端分离场景下的会话并发管理》本文介绍了在前后端分离架构下实现SpringSecurity会话并发管理的问题,传统Web开发中只需简单配置sessionManage... 目录背景分析传统 web 开发中的 sessionManagement 入口ConcurrentSess

MySQL中读写分离方案对比分析与选型建议

《MySQL中读写分离方案对比分析与选型建议》MySQL读写分离是提升数据库可用性和性能的常见手段,本文将围绕现实生产环境中常见的几种读写分离模式进行系统对比,希望对大家有所帮助... 目录一、问题背景介绍二、多种解决方案对比2.1 原生mysql主从复制2.2 Proxy层中间件:ProxySQL2.3

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

MySQL主从复制与读写分离的用法解读

《MySQL主从复制与读写分离的用法解读》:本文主要介绍MySQL主从复制与读写分离的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、主从复制mysql主从复制原理实验案例二、读写分离实验案例安装并配置mycat 软件设置mycat读写分离验证mycat读

ShardingSphere之读写分离方式

《ShardingSphere之读写分离方式》:本文主要介绍ShardingSphere之读写分离方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录ShardingSphere-读写分离读写分离mysql主从集群创建 user 表主节点执行见表语句项目代码读写分

spring security 超详细使用教程及如何接入springboot、前后端分离

《springsecurity超详细使用教程及如何接入springboot、前后端分离》SpringSecurity是一个强大且可扩展的框架,用于保护Java应用程序,尤其是基于Spring的应用... 目录1、准备工作1.1 引入依赖1.2 用户认证的配置1.3 基本的配置1.4 常用配置2、加密1. 密

Java如何将文件内容转换为MD5哈希值

《Java如何将文件内容转换为MD5哈希值》:本文主要介绍Java如何将文件内容转换为MD5哈希值的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java文件内容转换为MD5哈希值一个完整的Java示例代码代码解释注意事项总结Java文件内容转换为MD5

Spring Security+JWT如何实现前后端分离权限控制

《SpringSecurity+JWT如何实现前后端分离权限控制》本篇将手把手教你用SpringSecurity+JWT搭建一套完整的登录认证与权限控制体系,具有很好的参考价值,希望对大家... 目录Spring Security+JWT实现前后端分离权限控制实战一、为什么要用 JWT?二、JWT 基本结构