哈希表也叫做散列表。在各种语言中都有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. UDP通讯协议

    常见的通讯协议有udp和tcp. 先来简单了解一下这两个协议各自的特点: UDP: --将数据及源.目的封装在数据包中,不需要建立连接: --每个数据包的大小限制在64k以内: --因无连接,是不可靠 ...

  2. Struts2+Spring+Hibernate 三大框架的合并集成

    这次来看看Struts2+Spring+Hibernate三大框架的整合应用,主要是Spring和Hibernate框架的整合,因为前边已经将Strtus2+Spring整合过了基本一样.  首先看一 ...

  3. 在eclipse中使用svn

    作为一名程序员,svn是比较常用也必然会使用到的一个工具,它的全拼为Subversion,是一个开源的版本控制系统,可以对每次修改的文件和目录进行准确记录,以便在使用的时候及时提取.本文主要介绍如何在 ...

  4. 使用<base target="_self" /> IE6 cann't open the Internet site 已终止操作

    今日发现一个问题,我的网页需要用到<base target="_self" />,经测试IE8,9  谷歌   火狐全都正常,但是IE6 showModalDialog ...

  5. Leetcode 238 Product of Array Except Self 时间O(n)和空间O(1)解法

    1. 问题描写叙述 给定一个n个整数的数组(n>1n>1)nums,返回一个数组output,当中的元素outputioutput_i的值为原数组nums中除numsinums_i之外的全 ...

  6. C/C++笔试准备(1)

    题目:用递归的算法实现这样一个函数,计算一个字符串最大连续相同字符数,输入aaabbc,输出3:输入bbc,输出2 #include <iostream> using namespace ...

  7. Swift学习之类和结构体的创建

    随着一步步的学习,学习到的新知识越来越多了,不管是新的还是旧的,都禁不住时间的堆积,再熟悉的知识点时间久了都会渐渐的忘记,也许这就是人们生活中一种潜在的惰性吧,看似非常熟悉的东西,等到真正要用的时候, ...

  8. Java中遍历Map对象的方法

    方法一: 在for-each循环中使用entries来遍历 这是最常见的遍历方式,在需要获取key和value时使用. Map<Integer, Integer> map = new Ha ...

  9. django中使用原生sql

    在Django中使用原生Sql主要有以下几种方式: 一:extra:结果集修改器,一种提供额外查询参数的机制 二:raw:执行原始sql并返回模型实例 三:直接执行自定义Sql ( 这种方式完全不依赖 ...

  10. Android Activity和intent