哈希表也叫做散列表。在各种语言中都有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简单实现的更多相关文章

  1. 数据结构HashMap哈希表原理分析

    先看看定义:“散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度. 哈希 ...

  2. 哈希表(hashtable)的javascript简单实现

    javascript中没有像c#,java那样的哈希表(hashtable)的实现.在js中,object属性的实现就是hash表,因此只要在object上封装点方法,简单的使用obejct管理属性的 ...

  3. 【Java源码】集合类-JDK1.8 哈希表-红黑树-HashMap总结

    JDK 1.8 HashMap是数组+链表+红黑树实现的,在阅读HashMap的源码之前先来回顾一下大学课本数据结构中的哈希表和红黑树. 什么是哈希表? 在存储结构中,关键值key通过一种关系f和唯一 ...

  4. C++ 哈希表 (hashtable) 用于保存简单的数据,及数据查找,数据删除

    /*hashtable.h*/ #include<iostream> #include <string> #include<vector> using namesp ...

  5. C语言实现简单的哈希表

    这是一个简单的哈希表的实现,用c语言做的. 哈希表原理 这里不讲高深理论,只说直观感受.哈希表的目的就是为了根据数据的部分内容(关键字),直接计算出存放完整数据的内存地址. 试想一下,如果从链表中根据 ...

  6. 开地址哈希表(Hash Table)的原理描述与冲突解决

    在开地址哈希表中,元素存放在表本身中.这对于某些依赖固定大小表的应用来说非常有用.因为不像链式哈希表在每个槽位上有一个"桶"来存储冲突的元素,所以开地址哈希表需要通过另一种方法来解 ...

  7. C# 哈希表HashTable的简单使用

    本人C#程序菜鸟级别的存在,写博客一方面是为了知识的共享,另一方面也是为了督促自己:大神,可以忽略这篇文文的.废话到此...... 哈希表是可以直接进行访问的数据结构,在形式上是类似字典的.不同的是, ...

  8. 48 容器(七)——HashMap底层:哈希表结构与哈希算法

    哈希表结构 哈希表是由数组+链表组成的,首先有一个数组,数组的每一个位置都用来存储一个链表,链表的基本节点为:[hash值,key值,value值,next],当存入一个键值对时,首先调用hashco ...

  9. 数据结构和算法(Golang实现)(26)查找算法-哈希表

    哈希表:散列查找 一.线性查找 我们要通过一个键key来查找相应的值value.有一种最简单的方式,就是将键值对存放在链表里,然后遍历链表来查找是否存在key,存在则更新键对应的值,不存在则将键值对链 ...

随机推荐

  1. POJ3261-哈希

    这个题让求至少出现K次的最大长度的子串,属于最大化最小值问题,首先应该想到二分求字串的长度,二分的过程是O(logN)的,注意judge的时候怎样判断是否满足情况以及满足情况后l,r的变化.可以给每一 ...

  2. SOCKET 实现NAT 穿越

    在当前IPv4NAT盛行的网络环境下,两个用户要直接进行P2P连接是非常困难的.较好的解决办法是借助含公网的用户或是服务器中介实现P2P连接. NAT:Network Address Translat ...

  3. jdbc连接数据库工具类

    import java.lang.reflect.Field; import java.sql.Connection; import java.sql.DriverManager; import ja ...

  4. HDOJ-1019 Least Common Multiple

    http://acm.hdu.edu.cn/showproblem.php?pid=1019 题意:给出n个数,求它们的最小公倍数 对于n个数,它们的最小公倍数等于[前n-1个数的最小公倍数和第n个数 ...

  5. Micro Python - Python for microcontrollers

    Micro Python - Python for microcontrollers MicroPython

  6. 禁用UITableViewCell 重用机制

    有时候不想让Cell重用,怎么办勒.接下来介绍两种方法 方法一 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAt ...

  7. IOS Main函数

    int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSS ...

  8. OpenReports中文支持方案

    此文章在<OpenReports中文支持完全解决方案.doc>的基础上做优化,并贴出代码.已测试通过. 一.主要解决的问题 1 页面显示支持中文 2 与服务器或数据库的交互支持中文 3 查 ...

  9. [Elasticsearch] 部分匹配 (三) - 查询期间的即时搜索

    本章翻译自Elasticsearch官方指南的Partial Matching一章. 查询期间的即时搜索(Query-time Search-as-you-type) 如今让我们来看看前缀匹配可以怎样 ...

  10. IOS中的各种Picker

    简述 在应用的一些设置中经常要用到一些Picker来快速帮助用户选定取值,一般会用到的有UIDatePicker,UIPickerView以及UIImagePickerController. 初始界面 ...