我是靠谱客的博主 知性学姐,最近开发中收集的这篇文章主要介绍设计哈希映射(详解)不使用任何内建的哈希表库设计一个哈希映射,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

706. 设计哈希映射

不使用任何内建的哈希表库设计一个哈希映射

具体地说,你的设计应该包含以下的功能

put(key, value):向哈希映射中插入(键,值)的数值对。如果键对应的值已经存在,更新这个值。
get(key):返回给定的键所对应的值,如果映射中不包含这个键,返回-1。
remove(key):如果映射中存在这个键,删除这个数值对。

示例:
MyHashMap hashMap = new MyHashMap();
hashMap.put(1, 1);
hashMap.put(2, 2);
hashMap.get(1);
// 返回 1
hashMap.get(3);
// 返回 -1 (未找到)
hashMap.put(2, 1);
// 更新已有的值
hashMap.get(2);
// 返回 1
hashMap.remove(2);
// 删除键为2的数据
hashMap.get(2);
// 返回 -1 (未找到)

注意:

所有的值都在 [0, 1000000]的范围内。
操作的总数目在[1, 10000]范围内。
不要使用内建的哈希库。

代码如下:

class MyHashMap {
static class Node {//静态内部类
public int data;
public int value;
public Node next;
public Node (int data, int value) {
this.data = data;
this.value = value;
}
}
public Node[] array;
public int usedSize;
/** Initialize your data structure here. */
public MyHashMap() {
this.array = new Node[10];
this.usedSize = 0;
}
/** value will always be non-negative. */
public void put(int key, int value) {
int index = key % array.length;
//如果里面已经有相同的key了,那么就更新它的value就行了
for (Node cur = array[index]; cur != null; cur = cur.next) {
if(cur.data == key) {
cur.value = value;
return;
}
}
//里面没有存放这个key
这里使用的是头插法。
Node node = new Node(key,value);
node.next = array[index];
array[index] = node;
usedSize++;
//这个时候还要考虑负载因子,看是否需要扩容
if (loadFactor() > 0.75) {
resize();
}
}
//计算负载因子
public double loadFactor() {
return usedSize*1.0 / array.length;
}
//扩容
(注意这里需要重新哈希一下了)
public void resize() {
Node[] newArray = new Node[array.length*2];
for(int i = 0; i < array.length; i++) {
Node curNext = null;
for(Node cur = array[i];cur != null; cur = curNext) {
curNext = cur.next;
int index = cur.data % newArray.length;
cur.next = newArray[index];
newArray[index] = cur;
}
}
this.array = newArray;
}
/** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
public int get(int key) {
int index = key % this.array.length;
for (Node cur = array[index]; cur != null; cur = cur.next) {
if (cur.data == key) {
return cur.value;
}
}
return -1;
}
/** Removes the mapping of the specified value key if this map contains a mapping for the key */
public void remove(int key) {
int index = key % this.array.length;
Node curNext = null;
Node prev = null;
for (Node cur = array[index]; cur != null; cur = curNext) {
curNext = cur.next;
if (cur.data == key) {
if (cur == array[index]) {//头节点
array[index] = curNext;
}else {
prev.next = curNext;
}
return;
}
prev = cur;
}
}
}
/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap obj = new MyHashMap();
* obj.put(key,value);
* int param_2 = obj.get(key);
* obj.remove(key);
*/

解题思路:

​ hashMap在jdk1.8中使用的是数组+链表+红黑树,我们这里使用的是数组加链表来实现的。需要特别注意的是哈希函数和负载因子,而且扩容的时候需要重新哈希。然后就是链表的操作了。这里的链表是我们自己实现的。然后jdk1.8中的插入是尾插法,这里我们使用的是头插法实现的。详细了解可以去看看源码。

最后

以上就是知性学姐为你收集整理的设计哈希映射(详解)不使用任何内建的哈希表库设计一个哈希映射的全部内容,希望文章能够帮你解决设计哈希映射(详解)不使用任何内建的哈希表库设计一个哈希映射所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部