java hashtable 数据结构_java数据结构——哈希表(HashTable)

哈希表提供了快速的插入操作和查找操作,每一个元素是一个key-value对,其基于数组来实现。

一、Java中HashMap与Hashtable的区别:

HashMap可以接受null键值和值,而Hashtable则不能。

Hashtable是线程安全的,通过synchronized实现线程同步。而HashMap是非线程安全的,但是速度比Hashtable快。

这两个类有许多不同的地方,下面列出了一部分:

a) Hashtable 是 JDK 1 遗留下来的类,而 HashMap 是后来增加的。

b)Hashtable 是同步(synchronized)的,比较慢,但 HashMap 没有同步策略,所以会更快。

c)Hashtable 不允许有个空的 key,但是 HashMap 允许出现一个 null key。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classEmployee {privateString key;privateString name;publicString getKey() {returnkey;

}public voidsetKey(String key) {this.key =key;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicEmployee(String key, String name) {this.key =key;this.name =name;

}

}

员工类

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

importjava.math.BigInteger;public classHashTable {privateEmployee[] arr;publicHashTable() {

arr= new Employee[1000];

}public HashTable(intMaxsize) {

arr= newEmployee[Maxsize];

}//public void Insert(Employee emplo) {//以整型作为索引//arr[emplo.getKey()] = emplo;//}

public void Insert(Employee emplo) {//以字符串作为索引

arr[hashTable(emplo.getKey())] =emplo;

}//public Employee Find(int key) {//return arr[key];//}

publicEmployee Find(String key) {returnarr[hashTable(key)];

}public int hashTable(String key) {//转换AscII码存储,但存在码值重复问题

BigInteger hashVal = new BigInteger("0");

BigInteger pow27= new BigInteger("1");//int hashVal = 0;

int i = key.length() - 1;//int pow27 = 1;//27^0//for (; i >= 0; i--) {//int letter = key.charAt(i) - 96;//hashVal += letter;//}//return hashVal;//}

for (; i >= 0; i--) {int letter = key.charAt(i) - 96;

BigInteger letterB= newBigInteger(String.valueOf(letter));

hashVal= hashVal.add(letterB.multiply(pow27));//hashVal += letter * pow27;//hashVal += letter * pow27;//这里会溢出//pow27*=27

pow27 = pow27.multiply(new BigInteger(String.valueOf(27)));

}//return hashVal % arr.length;

return hashVal.mod(newBigInteger(String.valueOf(arr.length))).intValue();

}

}

方法类

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classDemo {public static voidmain(String[] args) {

HashTable ht= newHashTable();/*ht.Insert(new Employee(1, "Ally"));

ht.Insert(new Employee(2, "Jion"));

ht.Insert(new Employee(3, "Micale"));

ht.Insert(new Employee(4, "Lily"));

System.out.println(ht.Find(2).getName());*/ht.Insert(new Employee("aka", "74"));

System.out.println(ht.Find("aka").getName());

}

}

演示类

链地址法

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classLinkList {private Node first;//火车头,保存头结点的一个指向

public LinkList() {//初始化

first = null;

}public Node deleteFirst() {//删除头结点

first = first.next;//头结点为头结点的下一个

returnfirst;

}public Node find(String key) {//按值查找,返回null或索引值

Node current = first;//从头结点开始

while (!key.equals(current.emplo.getKey())) {if (current.next == null) {//尾结点后继为null

return null;

}

current=current.next;

}return current;//找到返回

}public Node delete(String key) {//删除任意结点

Node current =first;

Node previous=first;while (!key.equals(current.emplo.getKey())) {//找到current返回true !true = false

if (current.next == null) {//没有找到

return null;

}

previous= current;//保存邻近的两个结点

current =current.next;

}if (current == first) {//第一个结点

first =first.next;

}else {//后面的结点

previous.next = current.next;//上一个结点的下一个变为当前结点的下一个,当前结点删除

}return current;//结点类,返回结点类型

}public void insert(Employee emplo) {//在头结点之后插入

Node node = new Node(emplo);//创建新的结点//这里深深体会一下精妙之处,first保存着一个指向

node.next = first;//图示第一步

first = node;//图示第二步

}

}

链表

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public class Node {//包装车厢

/*** 链结点*/

public Employee emplo;//数据域

public Node next;//指针域,后指针

public Node(Employee emplo) {//构造函数

this.emplo =emplo;

}

}

结点

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

importjava.math.BigInteger;public classHashTable {private LinkList[] arr; //每个数值对应一个链表

publicHashTable() {

arr= new LinkList[100];

}public HashTable(intMaxsize) {

arr= newLinkList[Maxsize];

}public void Insert(Employee emplo) {//以字符串作为索引

String key =emplo.getKey();int hashVal =hashTable(key);if (arr[hashVal] == null) {

arr[hashVal]= newLinkList();

}

arr[hashVal].insert(emplo);

}publicEmployee Find(String key) {int hashVal =hashTable(key);returnarr[hashVal].find(key).emplo;

}publicEmployee Delete(String key) {int hashVal =hashTable(key);returnarr[hashVal].delete(key).emplo;

}public int hashTable(String key) {//转换AscII码存储,但存在码值重复问题

BigInteger hashVal = new BigInteger("0");

BigInteger pow27= new BigInteger("1");int i = key.length() - 1;for (; i >= 0; i--) {int letter = key.charAt(i) - 96;

BigInteger letterB= newBigInteger(String.valueOf(letter));

hashVal=hashVal.add(letterB.multiply(pow27));

pow27= pow27.multiply(new BigInteger(String.valueOf(27)));

}return hashVal.mod(newBigInteger(String.valueOf(arr.length))).intValue();

}

}

方法

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classDemo {public static voidmain(String[] args) {

HashTable ht= newHashTable();/*ht.Insert(new Employee(1, "Ally"));

ht.Insert(new Employee(2, "Jion"));

ht.Insert(new Employee(3, "Micale"));

ht.Insert(new Employee(4, "Lily"));

System.out.println(ht.Find(2).getName());*/ht.Insert(new Employee("a", "Jack")); //开放地址法

ht.Insert(new Employee("ct","Rose"));

ht.Insert(new Employee("b", "Upon"));

System.out.println(ht.Find("a").getName());//打印对象

System.out.println(ht.Find("ct").getName());

System.out.println(ht.Find("b").getName());

System.out.println(ht.hashTable("a"));

System.out.println(ht.hashTable("ct"));

}

}

测试

0b6c7df615bb63cd894fba0bcf53964d.png

b19566cf91dba756b0f49825b992e740.png

参考文献:

https://www.cnblogs.com/aeolian/p/8468632.html

https://www.cnblogs.com/williamjie/p/9099141.html

http://www.luyixian.cn/news_show_10979.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值