一、手撕哈希表?
哈希表包括插入,删除,包含操作
以插入操作为例,其手撕的过程主要分为以下几步:
1.把插入的对象转为int类型,调用hashCode()函数就可以了;
2.转为合法的下标(哈希函数:hash(key)=key%capacity),如:int index=hashValue%array.length;
3.遍历index位置处的链表,确定key在不在元素中
4.把key装进结点中,并插入到对应的链表中
5.维护元素的个数
6…通过维护负载因子,进而维护较低的负载因子
这六个步骤缺一不可,在面试的时候,主要是要用自己的将这六大步骤准确描述描述出来。这六大步骤记住了,代码也就比较容易写出来。
二、手撕过程
1.插入
插入过程就是以上六大步骤,主要在扩容的需要注意不能直接把原来链表的元素直接搬过去,扩容方法详细书写在后面。
public class MyHashTable {
//实现一个HashTable首先需要一个数组
private Node[] array=new Node[11];
//维护哈希表中所有元素的个数
private int size;
//插入操作
public boolean insert(Integer key){
//1.把对象转为int类型
int hashValue=key.hashCode();
//2.把hashValue转成合法的下标
int index=hashValue%array.length;
//3.遍历index位置处的链表,确定key在不在元素中
Node current=array[index];
while(current!=null){
if(key.equals(current.key)){
return false;
}
current=current.next;
}
//4.把key装进结点中,并插入到对应的链表中
Node node=new Node(key);
node.next=array[index];
array[index]=node;
//5.维护元素的个数
size++;
//6.通过维护负载因子,进而维护较低的负载因子
if(size/array.length*100>75){
dilatation();
}
return true;
}
2.删除
删除的过程也包括以上的六大步骤,不同的是还要定义一个要删除元素的前驱节点,容易出错的点就是:当prev为null时,删除的就是其头结点,不能忽略这一步。
public boolean remove(Integer key){
//1.采用hashCode转为int类型
int hashValue=key.hashCode();
//2.得到合法的下标
int index=hashValue%array.length;
Node prev=null;
Node current=array[index];
while(current!=null){
//删除操作
if(key.equals(current.key)){
if(prev!=null){
prev.next=current.next;
}else{
//prev为null,删除的是头节点
array[index]=current.next;
}
size--;
return true;
}
prev=current;
current=current.next;
}
return false;
}
3.包含
public boolean contains(Integer key){
int hashValue=key.hashCode();
int index=hashValue%array.length;
Node current=array[index];
while(current!=null){
if(key.equals(current.key)){
return true;
}
current=current.next;
}
return false;
}
4.扩容
扩容的时候,要把原来的元素搬到新的数组中,但是不能按原链表搬,因为保存元素的下标和数组长度有关,数组的长度变了,下标也会变化,所以要重新计算每一个元素的下标。
public void dilatation(){
Node[] newArray=new Node[array.length*2];
for(int i=0;i<array.length;i++){
Node current=array[i];
while (current!=null){
Integer key=current.key;
int hashValue=key.hashCode();
int index=hashValue%newArray.length;
//头插
Node node=new Node(key);
node.next=newArray[index];
newArray[index]=node;
current=current.next;
}
}
array=newArray;
}