哈希表原理及hashmap简单实现
哈希表也叫做散列表。在各种语言中都有hashmap的实现。其最突出的优点是查找和插入以及删除具有常数的时间复杂度
我们可以把哈希表理解为数组+链表
数组具有常数复杂度的查找,为什么呢,因为数组是在内存中连续存放,当我们索引某个位置的元素时候根据
索引值自动计算距离数组首元素起始位置的内存间隔。然而对于中间插入和中间删除元素,数组会将待插入位
置后面的原素先整体向后移动一个位置再将元素插入到待插入的位置。所以时间复杂度为O(n)对于大规模的数
组来说,开销是很大的。
然而链表正相反。由于链表是存储在内存中不连续的位置,并且链表之间是通过链表指针链接到一起。前一个元
素保存后一个元素的指针,我们也称之为前一个元素指向后一个元素。当我们在链表中寻找某个元素的时候必须
按照链表指针遍历整个链表,时间复杂度为O(n)但是针对插入很删除来说,我们只需要更改待需要操作的链表元素
的指针即可,时间复杂度为O(1).
那么我们可以不可以把两者结合起来组合成一种新的数据结构呢,这种数据结构即能实现常数复杂度的索引也能
实现常数复杂度的插入和删除。当然哈希表应运而生。
哈希表的原理可以简述为(简述插入和索引操作):
插入:当我们插入hashmap['key']=value时,先将key映射为hashcode,然而用hashcode对哈希表长度取模获得索引
位置。然后将值插入到索引位置。(这里可能会存在冲突,即相同的Key的hashcode相同)
索引:当我们索引某个值的时候,先将key映射为hashcode,然后将key对哈希表长度取模,然后取出该索引位置上
的值。
下面我简单实现了一个哈希表,这仅仅是为了说明
哈希的原理。
简单hashmap类定义:
#include<iostream>
using namespace std;
class MySimpleHashmap
{
public:
int *Array;
enum{MaxHashSize=}; int hashcode(int &key); public:
MySimpleHashmap();
~MySimpleHashmap(); int& operator[](int & key); }; int& MySimpleHashmap::operator [](int& key)
{
return Array[hashcode(key)];
} MySimpleHashmap::MySimpleHashmap()
{
Array=new int[MaxHashSize]; for(int i=;i<MaxHashSize;i++)
{
Array[i]=;
}
} MySimpleHashmap::~MySimpleHashmap()
{
delete[] Array;
Array=NULL;
} int MySimpleHashmap::hashcode(int& key)
{
while(true)
{
if(Array[key%MaxHashSize]==)
{
return key%MaxHashSize;
}
else
{
key++;
}
}
}
main.c
#include "VpoetHashmap.h"
#include <iostream>
using namespace std; int main()
{
MySimpleHashmap MyHash; int key1=; //hashkey=1
int key2=; //hashkey=2
int key3=; //hashkey=2冲突
int key4=; //hashkey=4
int key5=; //hashkey=5 MyHash[key1]=;
MyHash[key2]=;
MyHash[key3]=;
MyHash[key4]=;
MyHash[key5]=; cout<<"hash table node1:"<<MyHash.Array[]<<endl;
cout<<"hash table node2:"<<MyHash.Array[]<<endl;
cout<<"hash table node3:"<<MyHash.Array[]<<endl;
cout<<"hash table node4:"<<MyHash.Array[]<<endl;
cout<<"hash table node5:"<<MyHash.Array[]<<endl;
cout<<"hash table node6:"<<MyHash.Array[]<<endl;
cout<<"hash table node7:"<<MyHash.Array[]<<endl;
return ;
}
运行截图:
此外:本文只是粗略的引入了哈希表的原理。里面有几个很重要的地方还没有涉及到:
1.如果不同的的Key的hashcode相同,那么便引起了冲突。如何解决冲突呢。
2.哈希表的初始大小应该怎么取。
3.key映射成索引的hash函数有哪些,这些函数的取法与是否与冲突的次数有关。
4.什么是二次聚集
5.若哈希表填满之后应该怎么扩展哈希表大小
6.装填因子是什么。
这些问题都是在实现hashmap中十分重要的点。
哈希表原理及hashmap简单实现的更多相关文章
- 数据结构HashMap哈希表原理分析
先看看定义:“散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度. 哈希 ...
- 哈希表(hashtable)的javascript简单实现
javascript中没有像c#,java那样的哈希表(hashtable)的实现.在js中,object属性的实现就是hash表,因此只要在object上封装点方法,简单的使用obejct管理属性的 ...
- 【Java源码】集合类-JDK1.8 哈希表-红黑树-HashMap总结
JDK 1.8 HashMap是数组+链表+红黑树实现的,在阅读HashMap的源码之前先来回顾一下大学课本数据结构中的哈希表和红黑树. 什么是哈希表? 在存储结构中,关键值key通过一种关系f和唯一 ...
- C++ 哈希表 (hashtable) 用于保存简单的数据,及数据查找,数据删除
/*hashtable.h*/ #include<iostream> #include <string> #include<vector> using namesp ...
- C语言实现简单的哈希表
这是一个简单的哈希表的实现,用c语言做的. 哈希表原理 这里不讲高深理论,只说直观感受.哈希表的目的就是为了根据数据的部分内容(关键字),直接计算出存放完整数据的内存地址. 试想一下,如果从链表中根据 ...
- 开地址哈希表(Hash Table)的原理描述与冲突解决
在开地址哈希表中,元素存放在表本身中.这对于某些依赖固定大小表的应用来说非常有用.因为不像链式哈希表在每个槽位上有一个"桶"来存储冲突的元素,所以开地址哈希表需要通过另一种方法来解 ...
- C# 哈希表HashTable的简单使用
本人C#程序菜鸟级别的存在,写博客一方面是为了知识的共享,另一方面也是为了督促自己:大神,可以忽略这篇文文的.废话到此...... 哈希表是可以直接进行访问的数据结构,在形式上是类似字典的.不同的是, ...
- 48 容器(七)——HashMap底层:哈希表结构与哈希算法
哈希表结构 哈希表是由数组+链表组成的,首先有一个数组,数组的每一个位置都用来存储一个链表,链表的基本节点为:[hash值,key值,value值,next],当存入一个键值对时,首先调用hashco ...
- 数据结构和算法(Golang实现)(26)查找算法-哈希表
哈希表:散列查找 一.线性查找 我们要通过一个键key来查找相应的值value.有一种最简单的方式,就是将键值对存放在链表里,然后遍历链表来查找是否存在key,存在则更新键对应的值,不存在则将键值对链 ...
随机推荐
- sae-v2ex 一个运行在SAE上的类似v2ex的轻型python论坛 - 技术讨论 - 云计算开发者社区 - Powered by Discuz!
sae-v2ex 一个运行在SAE上的类似v2ex的轻型python论坛 - 技术讨论 - 云计算开发者社区 - Powered by Discuz! sae-v2ex 一个运行在SAE上的类似v2e ...
- hdu 4405 Aeroplane chess(概率+dp)
Problem Description Hzz loves aeroplane chess very much. The chess map contains N+ grids labeled to ...
- qt model/view 架构基础介绍之QTreeWidget
# -*- coding: utf-8 -*- # python:2.x #说明:QTreeWidget用于展示树型结构,也就是层次结构同前面说的 QListWidget 类似,这个类需要同另外一个辅 ...
- iOS 3DES加密 和 java 3DES 解密
首先进入头文件: #import <CommonCrypto/CommonDigest.h> #import <CommonCrypto/CommonCryptor.h> #i ...
- 二叉排序树的创建删除中序输出&&平衡树
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #inclu ...
- iOS:UI系列之UINavigationController
又到了总结的时间了,突然间感觉时间过得好快啊, 总觉的时间不够用,但是这也没办法啊, 只有自己挤时间了,虽然是零基础,但是这并不能代表什么啦,只要努力,收获总还是有的, 同时我也相信广大的博友肯定也有 ...
- SQLLoader8(加载的数据中有换行符处理方法)
SQLLDR加载的数据中有换行符处理方法1.创建测试表: CREATE TABLE MANAGER( MGRNO NUMBER, MNAME ), JOB ), REMARK ) ); 2.创建控制文 ...
- 失效的URL访问限制(转)
* 经常URL的保护仅仅是连接到该页面的链接不出现在未授权的用户面前.然而,一个有动机的.熟练的或者仅仅是幸运的黑客可能会找到并访问这些网页 , 调用这些功能并查看数据.在应用程序中,通过隐匿来实现安 ...
- UIAlertView与UIActionSheet
1.UIAlertView(警告框) 1.1 创建警告框,设置样式 - (IBAction)alertView:(UIButton *)sender {//创建button按钮 //创建警告框的实例 ...
- vs2013调试的时候卡顿
做毕业设计的时候忽然发现开始调试以后 会卡顿,这在前两天是没有的,纳尼,把我愁坏了. 首先以为程序或者vs出问题了.随后发现每次调试以后cpu急剧增加.随后就开始卡顿. 随后去网上搜索,发现两个答案. ...