自己动手实现java数据结构(五)哈希表
|
2. 当迭代器的下标到达当前插槽链表的末尾时,迭代器下标需要跳转到靠后插槽的第一个非空数据节点。
* 哈希表 迭代器实现
class Itr implements Iterator<EntryNode<K,1)"> {
* 迭代器 当前节点
* */
currentNode;
* 迭代器 下一个节点
* nextNode;
* 迭代器 当前内部数组的下标
* currentIndex;
* 默认构造方法
* private Itr(){
:::如果当前哈希表为空,直接返回
if(HashMap..isEmpty()){
;
}
:::在构造方法中,将迭代器下标移动到第一个有效的节点上
:::遍历内部数组,找到第一个不为空的数组插槽slot
int i=0; i<HashMap.:::设置当前index
this.currentIndex = i;
EntryNode<K,V> firstEntryNode = HashMap..elements[i];
:::找到了第一个不为空的插槽slot
if(firstEntryNode != :::nextNode = 当前插槽第一个节点
this.nextNode = firstEntryNode;
:::构造方法立即结束
;
}
}
}
@Override
hasNext() {
this.nextNode != );
}
@Override
public EntryNode<K,1)"> next() {
this.currentNode = .nextNode;
:::暂存需要返回的节点
EntryNode<K,V> needReturn = .nextNode;
:::nextNode指向自己的next
this.nextNode = .nextNode.next;
:::判断当前nextNode是否为null
this.nextNode == :::说明当前所在的桶链表已经遍历完毕
:::寻找下一个非空的插槽
int i=this.currentIndex+1; i<HashMap.:::设置当前index
i;
EntryNode<K,1)">.elements[i];
:::找到了后续不为空的插槽slot
){
:::nextNode = 当前插槽第一个节点
firstEntryNode;
:::跳出循环
break;
}
}
}
needReturn;
}
@Override
remove() {
this.currentNode == throw new IteratorStateErrorException("迭代器状态异常: 可能在一次迭代中进行了多次remove操作");
}
:::获得需要被移除的节点的key
K currentKey = .currentNode.key;
:::将其从哈希表中移除
HashMap..remove(currentKey);
:::currentNode设置为null,防止反复调用remove方法
;
}
}
5.哈希表性能5.1 空间效率:哈希表的空间效率很大程度上取决于负载因子。通常,为了保证哈希表查询的高效性,负载因子都设置的比较小(小于1),因而可能会出现许多空的插槽,浪费空间。 总体而言,哈希表的空间效率低于向量和链表。 5.2 时间效率:一般的,哈希表增删改查接口的时间复杂度都是O(1)。但是出现较多的hash冲突时,冲突范围内的key的增删改查效率较低,时间效率会有一定的波动。 总体而言,哈希表的时间效率高于向量和链表。 哈希表的时间效率很高,可天下没有免费的午餐,据统计,哈希表的空间利用率通常情况下还不到50%。 哈希表是一个使用空间来换取时间的数据结构,对查询性能有较高要求的场合,可以考虑使用哈希表。 6.哈希表总结6.1 当前版本缺陷至此,我们已经实现了一个基础的哈希表,但还存在许多明显缺陷: 1.当hash冲突比较频繁时,查询效率急剧降低。 jdk在1.8版本的哈希表实现(java.util.HashMap)中,对这一场景进行了优化。当内部桶链表的节点个数超过一定数量(默认为8)时,会将插槽中的桶链表转换成一个红黑树(查询效率为O(logN))。 2.不支持多线程 在多线程的环境,并发的访问一个哈希表会导致诸如:扩容时内部节点死循环、丢失插入数据等异常情况。 6.2 查询特定元素的方法我们目前查询特定元素有几种不同的方法: 1.顺序查找 在无序向量或者链表中,查找一个特定元素是通过从头到尾遍历容器内元素的方式实现的,执行速度正比于数据量的大小,顺序查找的时间复杂度为O(n),效率较低。 2.二分查找 在有序向量以及后面要介绍的二叉搜索树中,由于容器内部的元素是有序的,因此可以通过二分查找比较的方式查询特定的元素,二分查找的时间复杂度为O(logN),效率较高。 3.哈希查找 在哈希表中,通过直接计算出数据hash值对应的插槽(slot)(时间复杂度O(1)),查找出对应的数据,哈希查找的时间复杂度为O(1),效率极高。 特定元素的查找方式和排序算法的关系 1.顺序查找对应冒泡排序、选择排序等,效率较低,时间复杂度(O(n2))。 2.二分查找对应快速排序、归并排序等,效率较高,时间复杂度(O(nLogn))。 3.哈希查找对应基排序,效率极高,时间复杂度(O(n))。 在大牛刘未鹏的博客中有更为详细的说明,http://mindhacks.cn/2008/06/13/why-is-quicksort-so-quick。 6.3 完整代码(编辑:清远站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

