您的位置:首页 > 理论基础 > 数据结构算法

数据结构-Java实现散列表

2016-12-02 18:26 357 查看

概念

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

给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。



本文使用除留取余hash算法,使用链地址法处理地址冲突,在java语言中实现散列表的数据接口

节点数据结构

package com.billJiang.hashtable;

/**
* Created by billJiang on 2016/11/30.
* hashtable 节点 可能发生碰撞
*/
public class Entry<T> {
int key;
T item;
Entry<T> next;

public Entry(int key,T item,Entry<T> next){
this.key=key;
this.item=item;
this.next=next;
}
}


实现代码

package com.billJiang.hashtable;

import java.util.Arrays;

/**
* Created by billJiang on 2016/11/30.
*/
public class HashTable<T> {
private static final int INITIAL_SIZE=3;
private static final float LOAD_FACTOR=0.75f;
private  Entry<T>[] table;

private int size=0;
private int use=0;

public HashTable() {
table = new Entry[INITIAL_SIZE];
}

public void put(int key,T item){
int index=hash(key);
if(table[index]==null){
table[index]=new Entry(-1,null,null);
}
Entry e=table[index];
//未存过值
if(e.next==null){
Entry entry=new Entry(key,item,null);
e.next=entry;
size++;
use++;
if(use>=table.length*LOAD_FACTOR){
resize();
}
}else{
//已经存在值,替换
for(e=e.next;e!=null;e=e.next){
if(e.key==key){
e.item=item;
return;
}
}
//追加
Entry temp=table[index].next;
Entry entry=new Entry(key,item,temp);
table[index].next=entry;
size++;
}

}

public void remove(int key){
int index=hash(key);
Entry e=table[index];
Entry pre=table[index];
for(e=e.next;e!=null;e=e.next){
if(e.key==key){
pre.next=e.next;
size--;
//TODO 24页缺少以下两行代码
if (pre.key == -1 && e.next == null)
use--;
break;
}
pre=e;
}

}

public T get(int key){
int index=hash(key);
Entry e=table[index];
for(e=e.next;e!=null;e=e.next){
if(e.key==key){
return (T) e.item;
}
}
return null;
}

public int size(){
return this.size;
}

public int getLength(){
return table.length;
}

private int hash(int key){
return key%table.length;
}

private void resize(){
Entry[] oldTable=table;
table=new Entry[table.length*2];
use=0;
for(int i=0;i<oldTable.length;i++){
if(oldTable[i]!=null&&oldTable[i].next!=null){
Entry e= oldTable[i];
Entry next=e.next;
while(e.next!=null){
int index=hash(next.key);
if(table[index]==null){
table[index]=new Entry(-1,null,null);
use++;
}
Entry temp=table[index].next;
table[index].next=new Entry(next.key,next.item,temp);
e=next;
}
}
}

}
}


测试代码

package com.billJiang.hashtable;

/**
* Created by billJiang on 2016/11/30.
*/
public class HashTableTest {

public static void main(String[] args) {
HashTable<String> table=new HashTable<String>();
table.put(1,"A");
table.put(2,"B");
table.put(3,"C");
table.put(4,"D");

table.put(5,"Hello world");

table.remove(1);

}
}


散列表的特点

访问速度很快

需要额外的空间

无序

可能发生碰撞

散列表经常用于缓存和快速查找。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 散列表