- 浏览: 122994 次
- 性别:
- 来自: 上海
最新评论
功能上于前面两个HashTable(-) ,HashTable(二) 一致,但实现上采用的链表表示每个Hash桶的位置,这样理论上不用考虑容量问题。实际中HashTable中的每个SortLink太长会导致效率低下,因此HashTable的初始大小比较重要。
链表使用的是有序链表SortLink,这样查找,删除的效率会提高一半,但是新增则会从O(1)降到链表的平均长度的一半。考虑链表不是太长,所以不会对效率产生太大的影响。但终究来说,这种实现更适合查询,不适合大量反复的插入。
关于可以插入的数据的键值,此处假设为整数。
代码中有许多辅助类
其中:
Item:装载有key(关键值)的数据
Node:单向链表的节点
SortLink:单向单端有序链表
HashTable:Hash表
其中SortLink,HashTable中的print方法纯粹是为了测试使用。
HashTable.main提供测试方法
class Item { private int key; private Object value; public Item(int key, Object value) { this.key = key; this.value = value; } public int key() { return key; } public Object value() { return value; } } class Node { private Item item; private Node next; public Node(Item item) { this.item = item; } public Item item() { return item; } public void next(Node next) { this.next = next; } public Node next() { return next; } } class SortLink { private Node first; public void add(Item item) { Node node = new Node(item); Node previous = null; Node current = first; while(current != null && current.item().key() < item.key()) { previous = current; current = current.next(); } node.next(current); if (previous == null) first = node; else previous.next(node); } public Item remove(int key) { if(first == null) return null; Node previous = null; Node current = first; while(current != null && current.item().key() < key) { previous = current; current = current.next(); } if(current != null && current.item().key() == key) { Item result = current.item(); if(previous == null) first = current.next(); else previous.next(current.next()); return result; } return null; } public Item find(int key) { if(first == null) return null; Node current = first; while(current != null && current.item().key() < key) current = current.next(); if(current != null && current.item().key() == key) return current.item(); else return null; } //测试专用 void print() { Node current = first; while(current != null) { System.out.print(current.item().key() + ","); current = current.next(); } System.out.println(); } } class HashTable { private SortLink[] array; HashTable(int size) { array = new SortLink[size]; } private int getHash(int key) { return key % array.length; } public void add(Item item) { int pos = getHash(item.key()); if(array[pos] == null) array[pos] = new SortLink(); array[pos].add(item); } public Item remove(int key) { int pos = getHash(key); if(array[pos] == null)return null; else return array[pos].remove(key); } public Item find(int key) { int pos = getHash(key); if(array[pos] == null)return null; else return array[pos].find(key); } //测试专用 public void print() { for(int i=0; i<array.length; i++) { if(array[i] != null) array[i].print(); } } public static void main(String[] args) { HashTable t = new HashTable(5); t.add(new Item(1,"hello")); t.add(new Item(6,"world")); t.add(new Item(11,"temp")); t.add(new Item(3,"jason")); t.add(new Item(104,"orange")); t.add(new Item(9,"peter")); t.print(); System.out.println("===================="); assert t.find(6).value().equals("world"); assert t.find(11).value().equals("temp"); assert t.find(104).value().equals("orange"); assert t.find(9).value().equals("peter"); assert t.find(87) == null; assert t.remove(3).value().equals("jason"); assert t.find(3) == null; assert t.remove(6).value().equals("world"); assert t.find(6) == null; t.print(); System.out.println("===================="); t.add(new Item(6,"temp")); assert t.find(6).value().equals("temp"); t.print(); System.out.println("==== OK ==="); } }
发表评论
-
Tree 红黑树
2008-05-01 17:23 2703红黑树是一种二叉平衡 ... -
Tree 2-3 平衡搜索树
2008-04-25 00:21 2335与2-3-4树 相似,2-3 平衡树是 ... -
Tree 2-3-4 平衡搜索树
2008-04-20 10:53 35002-3-4 平衡树是一种搜索树。每个节点可能会有2,3,4个子 ... -
Graph 图-邻接表法
2008-04-17 00:08 3008用邻接表法表示的双向图(改单向容易,只要修改connect,d ... -
Graph 图-邻接矩阵法
2008-04-16 22:56 3546用邻接矩阵法表示的双向图(改单向容易,只要修改connect, ... -
Heap 堆
2008-04-16 00:28 1480这里的堆不是java中内存分配的堆。只是一种数据结构。 堆是二 ... -
HashTable 基于开放地址法(二)
2008-04-14 19:40 2024与前一个HashTable 基本相同(方法说明请参照它),只是 ... -
HashTable 基于开放地址法
2008-04-13 22:59 1594该HashTable基于定常数组的开放地址法,搜索时采用线性探 ... -
Tree 二叉搜索树
2008-04-11 00:03 1721每个节点最多两个子节点,其中左边节点的值小于该节点的值,右边节 ... -
PriorityQueue 优先级队列
2008-04-06 17:57 3452提供一个基于链表的优先级队列,为了简便,只存储整数,假设数值越 ... -
PriorityQueue 优先级队列
2008-04-06 16:57 4350提供一个基于定长数组的优先级队列,为了简便,只存储整数,假设数 ... -
Queue 队
2008-04-06 13:36 1559指定最大值的队,底层用数组实现构造函数:指定最大容量put:放 ... -
ArrayStack 栈
2008-04-06 12:00 1307用Array实现的栈结构,功能与LinkedStack一致编程 ... -
Array 可变长可变维数组
2008-04-06 11:25 1844一个可以变长,变维的数组(只可以变大),用来替代多维数组基本做 ... -
StackDLink 双向链表
2008-04-05 23:20 1155用LinkedStack实现的双向链表,功能与DLink一致就 ... -
LinkedList 列表
2008-04-05 19:16 1466列表的简单实现,只能存储非负整数List 也属于ADT(抽象数 ... -
ArrayList 列表
2008-04-05 19:01 1209列表的简单实现,只能存储非负整数List 也属于ADT(抽象数 ... -
LinkedQueue 队
2008-04-05 18:43 1857实现了队的最简单功能:先进现出队属于ADT(抽象数据类型),其 ... -
DLink 双向双端链表
2008-04-05 18:06 1505DLink 实现一个简单的双向双端链表与Link一样,假定其之 ... -
LinkedStack 栈
2008-04-05 17:45 1128LinkedStack栈属于ADT(抽象数据类型),其提供同样 ...
相关推荐
2. 性能:HashMap的性能比HashTable好,因为HashMap使用数组和链表来存储键值对,而HashTable使用链表来存储键值对。 3. null键:HashMap允许存放null键和null值,而HashTable不允许存放null键和null值。 常见面试...
在链表法中,每个数组元素都是一个链表的头节点。当一个键被哈希到某个特定位置时,这个键值对会被添加到对应位置链表的末尾。如果多个键被哈希到同一个位置,它们会在同一个链表中形成链接,解决了键冲突的问题。...
查找操作同样计算哈希值,找到对应位置后,如果是链地址法,则需要遍历链表查找匹配的键。 4. 删除:删除操作涉及到如何找到要删除的键值对并从哈希表中移除。如果采用链地址法,可能需要遍历链表找到待删除节点,...
在“hashtable.c”和“hashtable.h”中,很可能采用了链地址法,即每个数组元素实际上是一个链表的头节点,相同哈希值的元素会被链接在一起。 3. 插入操作:当向哈希表中插入元素时,首先计算键的哈希值,然后在...
- **哈希表构建:** 采用质数取余法计算哈希值,利用链地址法解决哈希冲突。 - **插入方法:** 使用头插法,保证数据插入的高效性。 #### 三、项目功能详解 1. **员工信息的增加:** - **功能描述:** 管理员可...
如果多个键的哈希值相同,就会发生哈希冲突,这时哈希表通常采用链地址法或者开放寻址法来解决冲突。 在Java的`Hashtable`中,每个键值对都是通过`Entry`对象来表示的,这些`Entry`对象构成了内部的哈希表。插入...
ArrayList和Vector都是基于数组的实现,LinkedList是基于链表的实现。ArrayList和Vector的主要区别在于Vector使用了synchronized方法,线程安全,而ArrayList则没有。 ArrayList是Java中最常用的List实现类,它提供...
哈希表的工作原理基于哈希函数,它可以将任意大小的键(在本例中是IP地址)转化为固定大小的索引。这个索引用于在数组中定位对应的值。好的哈希函数能够将不同的键映射到不同的索引,减少冲突的可能性。在Java中,`...
HashMap是一种基于哈希表的集合类,它的存储结构是一个数组,每个元素是一个单链表的头节点,链表用来解决hash地址冲突问题。HashMap有四个构造方法,其中初始容量和加载因子是影响性能的重要参数。加载因子是哈希表...
常见的方法有开放寻址法(线性探测、二次探测、双哈希探测等)和链地址法(每个槽位存储一个链表)。 二、C语言实现哈希表 1. 定义数据结构:首先,我们需要定义哈希表的结构体,通常包括数组、元素个数、装载因子...
当发生哈希冲突时,即两个键的哈希值相同,Java的HashTable使用链地址法处理,即将这些键值对放在同一个数组位置的链表中。 在易语言中实现哈希表,我们需要考虑以下几点: 1. **数据结构**:设计一个结构体或类来...
在链地址法中,这可能意味着从链表中移除节点;在开放寻址法中,可能需要标记该位置为空。 在源代码工程中,可能会有以下关键文件和结构: - `hashtable.h`:头文件,定义哈希表的数据结构和公共接口。 - `...
5. **链地址法**:一种常见的处理哈希冲突的方法,每个数组槽位都连接一个链表,所有哈希到同一位置的键值对会被挂在这个链表上。查找时,先计算键的哈希值,然后遍历对应的链表。 6. **开放寻址法**:当发生冲突时...
在C#编程语言中,`Hashtable`是一种基于键值对的数据结构,它允许程序员存储和检索对象,通过关键字(key)来访问数据。本案例旨在深入解析`Hashtable`的使用方法,包括其基本操作、特点以及与其他数据结构的比较。 ...
TreeMap 是基于红黑树的数据结构,具有良好的性能和可扩展性。TreeMap 不允许键或值为 Null。 比较 在选择 Map 实现类时,需要考虑以下几个因素: * 是否需要同步?如果需要同步,可以选择 HashTable 或者使用 ...
在面试中,HashMap的设计和实现细节是常见的考察点,例如哈希冲突的解决策略(开放寻址法和链地址法)、负载因子的影响、扩容机制以及树化改造的过程。当HashMap的桶内元素过多时,会将链表转化为红黑树,以优化查找...
Polynomial:基于链表的多项式类,支持+、-、*运算符。 Stack:基于链表的堆栈。 StackBasedOnArray:基于数组的堆栈。 队列:基于链表的队列。 QueueBasedOnArray:基于数组的队列。 PriorityQueue:基于链表的优先...
常见的解决策略有开放寻址法(线性探测、二次探测、双哈希探测等)和链地址法(每个槽位是一个链表,冲突的元素添加到链表中)。 3. **装载因子**:装载因子是哈希表中已存储元素数量与总槽位数的比值,它直接影响...
哈希表是一种基于数组的数据结构,通过使用哈希函数将键映射到数组中的位置,从而实现快速查找。哈希表的主要优势在于查找、插入和删除操作的平均时间复杂度都可以达到O(1)。在Java中,`Map`接口提供了哈希表的功能...
提供的`hashcode`函数基于ELF哈希算法,它将字符串转换为整数,通过位运算减少冲突。ELF哈希算法的特点是快速且散列效果良好。 `hashtable_put`函数首先计算键的哈希值,然后通过哈希值找到对应的数组索引。如果...