Java_JDK_HashMap, HashTable, ConcurrentTable比较
Posted 江湖小妞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java_JDK_HashMap, HashTable, ConcurrentTable比较相关的知识,希望对你有一定的参考价值。
(一)TreeMap
TreeMap使用的是红黑树来实现的,所以重点是红黑树的插入和删除。
红黑树的3个特性:
- 根节点和所有外部节点的颜色都是黑色的;
- 从根节点到外部节点的途中没有连续两个节点的颜色是红色;
- 所有从根节点到外部节点的路径上都有相同数目的黑色节点。
下面来分析删除操作:
删除其实是非常麻烦的一个操作,但是这里Java并不是直接删除节点,而是找到一个最方便删除的节点替换至要删除的节点,然后删除即可。
什么意思呢?
简而言之,删除操作共分三种情况:
- 要删除的节点p是根叶子节点:
- 根据特性1,我们知道所有外部节点都是黑色的,故p一定是黑色的。但是这样冒然删去p一定会导致某条路径上少一个黑色节点,所以需要进行红黑调整;
- 要删除的节点p的左孩子或者右孩子中有一个是空的:
- 这种情况也很简单,直接修改指针删除p就可以了;
- 同样,如果删除的p是黑色的也要进行红黑调整;
- 要删除的节点p的左孩子和右孩子都不为空:
- 这时需要找到p的前驱,即左孩子的最右边或者右孩子的最左边;
- 然后将找到的前驱节点替换p,然后删除其前驱节点就OK啦~
在java中,删除主要分两个部分,一个是找到要删除的节点,是由deleteEntry(Entry<K, V> p)函数实现的;一个是调整颜色,是由fixAfterDeletion(Entry<K, V> x)实现的。
下面分别进行分析:
(1)deleteEntry函数:这里就是将上面三种情况考虑好,然后找到要删除的节点进行删除,中间调用了fixAfterDeletion函数。
/** * Delete node p, and then rebalance the tree. */ private void deleteEntry(Entry<K,V> p) { modCount++; size--; // If strictly internal, copy successor‘s element to p and then make p // point to successor. if (p.left != null && p.right != null) { //如果左右子树都不为空,则找到p的前驱(右子树的最左节点或者左子树的最右节点)s,然后用s来代替p,p指向s,则最终删除s即可。 Entry<K,V> s = successor(p); p.key = s.key; p.value = s.value; p = s; } // p has 2 children // Start fixup at replacement node, if it exists. //如果上一个if不满足,则说明至少有一个子树时空的,另replacement指向不空的那个子树的根节点,直接删除p即可 Entry<K,V> replacement = (p.left != null ? p.left : p.right); if (replacement != null) { // Link replacement to parent replacement.parent = p.parent; if (p.parent == null) root = replacement; else if (p == p.parent.left) p.parent.left = replacement; else p.parent.right = replacement; // Null out links so they are OK to use by fixAfterDeletion. p.left = p.right = p.parent = null; // Fix replacement,删除p之后,需要保持红黑树的特性,所以要调节他们的颜色 if (p.color == BLACK) fixAfterDeletion(replacement); } else if (p.parent == null) { // return if we are the only node. root = null; } else { // No children. Use self as phantom replacement and unlink. // p为叶子节点,可以直接删除,但如果是黑色节点需要调整 if (p.color == BLACK) fixAfterDeletion(p); if (p.parent != null) { if (p == p.parent.left) p.parent.left = null; else if (p == p.parent.right) p.parent.right = null; p.parent = null; } } }
(2)fixAfterDeletion()函数:
以上是关于Java_JDK_HashMap, HashTable, ConcurrentTable比较的主要内容,如果未能解决你的问题,请参考以下文章
leetcode@ [30/76] Substring with Concatenation of All Words & Minimum Window Substring (Hashtab