数据结构-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); } }
散列表的特点
访问速度很快需要额外的空间
无序
可能发生碰撞
散列表经常用于缓存和快速查找。
相关文章推荐
- Ruby中的数组和散列表的使用详解
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi