#include <iostream>
#include <cstring>
#include <string>
typedef unsigned int SIZE_T;
using namespace std; /** HashMap模板的C++实现,用拉链法解决冲突
*注意:需要为每一种KeyType两个仿函数:HashFunc and EqualKey
*/ template<typename KeyType, typename ValueType, typename HashFunc, typename EqualKey>
class HashMap{
#define DEFAULT_CAPACITY 43 // hash表初始化容量
#define LOADFACTOR 0.7 //负载因子 class KeyNode{ //存放key value对
public:
KeyType key;
ValueType value;
KeyNode *next;
KeyNode(){}
KeyNode(const KeyNode & rhs){
Assign(rhs);
}
const KeyNode & operator =(const KeyNode & rhs){
Assign(rhs);
return *this;
}
void Assign(const KeyNode & rhs){
this->key = rhs.key;
this->value = rhs.value;
this->next = rhs.next;
}
};
public:
HashMap(){
table = new KeyNode* [DEFAULT_CAPACITY];
::memset(table,,DEFAULT_CAPACITY * sizeof(KeyNode*));
size =;
capacity = DEFAULT_CAPACITY;
hash = HashFunc();
equal = EqualKey();
}
bool put(const KeyType & key, const ValueType & value){
SIZE_T index = hash(key) % capacity;
if(table[index] == NULL){
KeyNode *temp = new KeyNode();
temp->key = key;
temp->value = value;
temp->next =NULL;
table[index] = temp; }else{
KeyNode * pre=table[index]; while(pre->next != NULL){
if(equal(pre->key, key)) return false; //重复
pre = pre->next;
}
if(equal(pre->key, key)) return false; //重复
KeyNode *temp = new KeyNode();
temp->key = key;
temp->value = value;
temp->next =NULL;
pre->next = temp;
}
size ++;
if(size*1.0/capacity > LOADFACTOR) this->rehash();
return true;
}
bool remove(const KeyType & key){
SIZE_T index = hash(key) % capacity;
if(table[index] == NULL) return false;
KeyNode *temp = table[index];
if(equal(temp->key,key)){
table[index] = temp->next;
delete temp;
size --;
return true;
}
while(temp->next != NULL){
if(equal(temp->next->key, key)){
KeyNode * del = temp->next;
temp->next = del->next;
delete del;
size --;
return true;
}else{
temp = temp->next;
}
}
return false;
}
bool exist(const KeyType & key)const{
SIZE_T index = hash(key) % capacity;
if(table[index] == NULL) return false;
KeyNode *temp = table[index];
while(temp!= NULL){
if(equal(temp->key,key)) return true;
temp = temp->next;
}
return false;
}
/*
KeyNode find(const KeyType & key){
SIZE_T index = hash(key) % capacity;
if(table[index] == NULL) return NULL;
KeyNode *temp = table[index];
while(temp!= NULL){
if(equal(temp->key,key)) return *temp;
temp = temp->next;
}
return NULL;
}
*/
ValueType & operator[](const KeyType & key){
if(!exist(key)) put(key,ValueType());
return get(key);
}
SIZE_T Size(){
return size;
}
void display(){
cout << "size:"<<size<<endl;
for(SIZE_T i=;i<this->capacity;i++){
KeyNode * temp = table[i];
while(temp != NULL){
cout <<"("<<temp->key<<","<<temp->value<<") ";
temp = temp->next;
}
if(table[i]!=NULL) cout << endl;
}
}
~HashMap(){
this->destroy(table);
} private:
KeyNode ** table;
SIZE_T capacity;
SIZE_T size;
HashFunc hash;
EqualKey equal;
KeyNode ERROE; ValueType & get(const KeyType key){
SIZE_T index = hash(key) % capacity;
if(table[index] == NULL) return ERROE.value;
KeyNode *temp = table[index];
while(temp!= NULL){
if(equal(temp->key,key)) return temp->value;
temp = temp->next;
}
return ERROE.value;
}
//未实现
void rehash(){
//得到一个两倍左右大小的capacity(最好为素数),重新散列
}
void destroy(KeyNode ** hashtable){
for(SIZE_T i=;i<this->capacity;i++){
KeyNode * temp = hashtable[i];
while(temp != NULL){
KeyNode *del = temp;
temp = temp->next;
delete del;
}
}
delete []hashtable;
}
}; class HashFuncInt{
public:
SIZE_T operator()( int key)const{
return key;
}
}; class EqualFuncInt{
public:
bool operator()(int keyA, int keyB)const{
return keyA == keyB;
}
}; int main()
{
const int scale = ;
//内存泄露性能测试
while(false){
HashMap<int,int,HashFuncInt,EqualFuncInt> hm;
for(int i=;i<scale;i++){
hm.put(i,i*(i+));
}
hm.display();
for(int i=;i<scale;i+=)
hm.remove(i);
hm.display();
for(int i=;i<scale;i+=)
hm[i]=i*;
hm.display();
} //模板实用性测试 return ;
}

参考文献:

HashMap的C++实现的更多相关文章

  1. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  2. HashMap的工作原理

    HashMap的工作原理   HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间 ...

  3. 计算机程序的思维逻辑 (40) - 剖析HashMap

    前面两节介绍了ArrayList和LinkedList,它们的一个共同特点是,查找元素的效率都比较低,都需要逐个进行比较,本节介绍HashMap,它的查找效率则要高的多,HashMap是什么?怎么用? ...

  4. Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结

    2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分 ...

  5. 学习Redis你必须了解的数据结构——HashMap实现

    本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文链接博客园蜗牛 cnblogs.com\tdws . 首先提供一种获取hashCode的方法,是一种比较受欢迎的方式,该方法参照了一位园友的 ...

  6. HashMap与HashTable的区别

    HashMap和HashSet的区别是Java面试中最常被问到的问题.如果没有涉及到Collection框架以及多线程的面试,可以说是不完整.而Collection框架的问题不涉及到HashSet和H ...

  7. JDK1.8 HashMap 源码分析

    一.概述 以键值对的形式存储,是基于Map接口的实现,可以接收null的键值,不保证有序(比如插入顺序),存储着Entry(hash, key, value, next)对象. 二.示例 public ...

  8. HashMap 源码解析

    HashMap简介: HashMap在日常的开发中应用的非常之广泛,它是基于Hash表,实现了Map接口,以键值对(key-value)形式进行数据存储,HashMap在数据结构上使用的是数组+链表. ...

  9. java面试题——HashMap和Hashtable 的区别

    一.HashMap 和Hashtable 的区别 我们先看2个类的定义 public class Hashtable extends Dictionary implements Map, Clonea ...

  10. 再谈HashMap

    HashMap是一个高效通用的数据结构,它在每一个Java程序中都随处可见.先来介绍些基础知识.你可能也知 道,HashMap使用key的hashCode()和equals()方法来将值划分到不同的桶 ...

随机推荐

  1. restframework安装及APIView分析

    一.restframework的安装 方式一:pip3 install djangorestframework 方式二:pycharm图形化界面安装 方式三:pycharm命令行下安装(装在当前工程所 ...

  2. vuejs 学习旅程之 vue-resource

    如上图,所有的数据是从php获取过来的.所以就引出了vuejs 与php通信之说.百度了一下需要使用到一个vue插件 就是今天的主题 vuejs 学习旅程之 vue-resource vue-reso ...

  3. css:hover伪类的使用

    :hover的使用,即当鼠标指针移入元素时,所做出的样式设置 示例一 <!DOCTYPE html> <html lang="en"> <head&g ...

  4. Dom EVENT对象

    Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 事件通常与函数结合使用,函数不会在事件发生前被执行! 一:测试按键 function which ...

  5. zblog忘记后台密码怎么办 官方解决方案

    刚装的zblog还没开始研究,结果发现密码弄错了进不去后台,也是醉了 为节省时间,直接用官方方案,就是一个无密码进后台的文件.下载后把文件上传至网站根目录,然后直接访问后台修改密码 zblog密码找回 ...

  6. ios 开发发布证书配置详细流程

    iOS证书配置实践 本文参考了: iOS证书配置指南:http://dev.umeng.com/push/ios/license-configuration-guide 写在前面: 团队开发证书的管理 ...

  7. C# 对接腾讯企业邮接口----get/post请求

    在无所知之的情况下.来了一个对接接口的任务,没办法,只能根据前端时候的经验硬着头皮上了,随后又整理了一下写的方法,主要包括了部门的创建.更新.删除.查找.然后他们的前提是token的获取 首先HTTP ...

  8. 【js类库AngularJs】学习angularJs的指令(包括常见表单验证,隐藏等功能)

    [js类库AngularJs]学习angularJs的指令(包括常见表单验证,隐藏等功能) AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀 ...

  9. 《spss统计分析与行业应用案例详解》:实例九 单一样本t检验

    单一样本t检验的功能与意义 spss的单一样本t检验过程是瑕设检验中最基本也是最常用的方法之一,跟所有的假没检验一样,其依剧的基木原理也是统计学中的‘小概率反证法”原理.通过单一样本t检验.我们可以实 ...

  10. 如何使用ABAP Restful API进行代码的全文搜索

    使用这个代码全文搜索的前提条件,是在事务码SFW5里激活业务功能:SRIS_SOURCE_SEARCH 只需要把这个url贴到浏览器里: https://:44355/sap/bc/adt/repos ...