转载请以链接形式标明出处: 本文出自:103style的博客
base on jdk_1.8.0_77
红黑树 就是一种平衡的二叉查找树,说他平衡的意思是他不会变成“瘸子”,左腿特别长或者右腿特别长。除了符合二叉查找树的特性之外,还具体下列的特性:
节点是红色或者黑色根节点是黑色每个叶子的节点都是黑色的空节点(NULL)每个红色节点的两个子节点都是黑色的。从任意节点到其每个叶子的所有路径都包含相同的黑色节点。TreeMap 是一个 有序的key-value集合,它是通过 红黑树 实现的。 TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合。 TreeMap 实现了NavigableMap接口,意味着它 **支持一系列的导航方法。**比如返回有序的key集合。 TreeMap 实现了Cloneable接口,意味着 它能被克隆。 TreeMap 实现了java.io.Serializable接口,意味着 它支持序列化。
TreeMap基于红黑树 实现。该映射根据 其键的自然顺序进行排序,或者根据 创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。 TreeMap的基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n)。 另外,TreeMap是 非同步 的。 它的iterator 方法返回的 迭代器是fail-fastl 的。
排序默认是升序的,数字比较大小,字符串比较首字母,其他类型则需要自己实现Comparable接口,否则排序时会报错。
测试代码:
public static void main(String[] args) { List<Integer> s = new ArrayList<>(); for (int i = 0; i < 10; i++) { int t = (int) (Math.random() * 1000); s.add(t); } for (int i = 0; i < s.size(); i++) { System.out.print(s.get(i) + "----"); } System.out.println(); TreeMap<Integer, Integer> treeMap = new TreeMap<>(); for (int i = 0; i < s.size(); i++) { treeMap.put(s.get(i), s.get(i)); } Iterator<Map.Entry<Integer, Integer>> iterator = treeMap.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<Integer, Integer> next = iterator.next(); System.out.println(next.getKey() + "--" + next.getValue()); } }输出结果:
953----411----437----516----461----238----201----365----345----191---- 191--191 201--201 238--238 345--345 365--365 411--411 437--437 461--461 516--516 953--953数据类型修改为String之后输出结果为:
65----296----701----75----278----650----507----71----839----547---- 278--278 296--296 507--507 547--547 65--65 650--650 701--701 71--71 75--75 839--839TreeMap的构造函数主要是处理 key 的比较器。
public TreeMap() { comparator = null; } public TreeMap(Comparator<? super K> comparator) { this.comparator = comparator; } public TreeMap(Map<? extends K, ? extends V> m) { comparator = null; putAll(m); } public TreeMap(SortedMap<K, ? extends V> m) { comparator = m.comparator(); try { buildFromSorted(m.size(), m.entrySet().iterator(), null, null); } catch (java.io.IOException cannotHappen) { } catch (ClassNotFoundException cannotHappen) { } }从根节点开始,比较节点的目标的key的大小,
目标key>节点key:查找节点的右子树目标key<节点key:查找节点的左子树目标key=节点key:返回节点当在没有设置comparator的时候,get方法的key = null会抛出NullPointerException.
public V get(Object key) { TreeMapEntry<K,V> p = getEntry(key); return (p==null ? null : p.value); } final TreeMapEntry<K,V> getEntry(Object key) { // Offload comparator-based version for sake of performance if (comparator != null) return getEntryUsingComparator(key); if (key == null) throw new NullPointerException(); @SuppressWarnings("unchecked") Comparable<? super K> k = (Comparable<? super K>) key; TreeMapEntry<K,V> p = root; while (p != null) { int cmp = k.compareTo(p.key); if (cmp < 0) p = p.left; else if (cmp > 0) p = p.right; else return p; } return null; } final TreeMapEntry<K,V> getEntryUsingComparator(Object key) { @SuppressWarnings("unchecked") K k = (K) key; Comparator<? super K> cpr = comparator; if (cpr != null) { TreeMapEntry<K,V> p = root; while (p != null) { int cmp = cpr.compare(k, p.key); if (cmp < 0) p = p.left; else if (cmp > 0) p = p.right; else return p; } } return null; }获取 大于等于 key的最小节点。当 key比树中最大的key大时返回null。
public Map.Entry<K,V> ceilingEntry(K key) { return exportEntry(getCeilingEntry(key)); } final TreeMapEntry<K,V> getCeilingEntry(K key) { TreeMapEntry<K,V> p = root; while (p != null) { int cmp = compare(key, p.key); if (cmp < 0) { if (p.left != null) p = p.left; else return p; } else if (cmp > 0) { if (p.right != null) { p = p.right; } else { TreeMapEntry<K,V> parent = p.parent; TreeMapEntry<K,V> ch = p; while (parent != null && ch == parent.right) { ch = parent; parent = parent.parent; } return parent; } } else return p; } return null; }获取 小于等于 key的最大节点。当 key比树中最小的key小时返回null。
public K floorKey(K key) { return keyOrNull(getFloorEntry(key)); } final TreeMapEntry<K,V> getFloorEntry(K key) { TreeMapEntry<K,V> p = root; while (p != null) { int cmp = compare(key, p.key); if (cmp > 0) { if (p.right != null) p = p.right; else return p; } else if (cmp < 0) { if (p.left != null) { p = p.left; } else { TreeMapEntry<K,V> parent = p.parent; TreeMapEntry<K,V> ch = p; while (parent != null && ch == parent.left) { ch = parent; parent = parent.parent; } return parent; } } else return p; } return null; }获取 大于 key的最小节点,不存在则返回 null
public K higherKey(K key) { return keyOrNull(getHigherEntry(key)); } final TreeMapEntry<K,V> getHigherEntry(K key) { TreeMapEntry<K,V> p = root; while (p != null) { int cmp = compare(key, p.key); if (cmp < 0) { if (p.left != null) p = p.left; else return p; } else { if (p.right != null) { p = p.right; } else { TreeMapEntry<K,V> parent = p.parent; TreeMapEntry<K,V> ch = p; while (parent != null && ch == parent.right) { ch = parent; parent = parent.parent; } return parent; } } } return null; }获取 小于 key的最大节点,不存在则返回null.
public K lowerKey(K key) { return keyOrNull(getLowerEntry(key)); } final TreeMapEntry<K,V> getLowerEntry(K key) { TreeMapEntry<K,V> p = root; while (p != null) { int cmp = compare(key, p.key); if (cmp > 0) { if (p.right != null) p = p.right; else return p; } else { if (p.left != null) { p = p.left; } else { TreeMapEntry<K,V> parent = p.parent; TreeMapEntry<K,V> ch = p; while (parent != null && ch == parent.left) { ch = parent; parent = parent.parent; } return parent; } } } return null; }红黑树执行插入操作之后,要执行“插入修正操作”。 目的是:保红黑树在进行插入节点之后,仍然是一颗红黑树
public V put(K key, V value) { TreeMapEntry<K, V> t = root; if (t == null) { compare(key, key); // type (and possibly null) check root = new TreeMapEntry<>(key, value, null); size = 1; modCount++; return null; } int cmp; TreeMapEntry<K, V> parent; // split comparator and comparable paths Comparator<? super K> cpr = comparator; if (cpr != null) { do { parent = t; cmp = cpr.compare(key, t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } else { if (key == null) throw new NullPointerException(); @SuppressWarnings("unchecked") Comparable<? super K> k = (Comparable<? super K>) key; do { parent = t; cmp = k.compareTo(t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } TreeMapEntry<K, V> e = new TreeMapEntry<>(key, value, parent); if (cmp < 0) parent.left = e; else parent.right = e; fixAfterInsertion(e); size++; modCount++; return null; }通过getEntry(key)获取对应的节点,如果节点不为空,则更新值。
public V replace(K key, V value) { TreeMapEntry<K,V> p = getEntry(key); if (p!=null) { V oldValue = p.value; p.value = value; return oldValue; } return null; }通过getEntry(key)获取对应的节点,如果节点不为空,通过deleteEntry删除节点,并通过fixAfterDeletion(TreeMapEntry<K,V> x)重排树使之还是一颗 红黑树。fixAfterDeletion下面会介绍。
红黑树执行删除之后,要执行“删除修正操作”。 目的是保证:红黑树删除节点之后,仍然是一颗红黑树
当p有左右子树的时候,successor(p),及返回右子树上的最左边的树节点,即大于p的key的最小值。所以 replacement即为右子树上的最左边的树节点的右子树。否则 replacement即为p的左右子树中的一个。然后根据 replacement 不为空、是否是根节点、为空且不是根节点 3种情况删除节点p. public V remove(Object key) { TreeMapEntry<K,V> p = getEntry(key); if (p == null) return null; V oldValue = p.value; deleteEntry(p); return oldValue; } private void deleteEntry(TreeMapEntry<K, V> p) { modCount++; size--; if (p.left != null && p.right != null) {// p has 2 children TreeMapEntry<K, V> s = successor(p); p.key = s.key; p.value = s.value; p = s; } TreeMapEntry<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; p.left = p.right = p.parent = null; 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. 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; } } }置空root,修改 size 为 0.
public void clear() { modCount++; size = 0; root = null; }返回最左端的节点的key-value构建的SimpleImmutableEntry
public Map.Entry<K, V> firstEntry() { return exportEntry(getFirstEntry()); } final TreeMapEntry<K, V> getFirstEntry() { TreeMapEntry<K, V> p = root; if (p != null) while (p.left != null) p = p.left; return p; } static <K, V> Map.Entry<K, V> exportEntry(TreeMapEntry<K, V> e) { return (e == null) ? null : new AbstractMap.SimpleImmutableEntry<>(e); }返回最右端的节点的key-value构建的SimpleImmutableEntry
public Map.Entry<K,V> lastEntry() { return exportEntry(getLastEntry()); } final TreeMapEntry<K,V> getLastEntry() { TreeMapEntry<K,V> p = root; if (p != null) while (p.right != null) p = p.right; return p; } static <K, V> Map.Entry<K, V> exportEntry(TreeMapEntry<K, V> e) { return (e == null) ? null : new AbstractMap.SimpleImmutableEntry<>(e); }红黑树 的左旋
p 相当与上图的X.
private void rotateLeft(TreeMapEntry<K,V> p) { if (p != null) { TreeMapEntry<K,V> r = p.right; p.right = r.left; if (r.left != null) r.left.parent = p; r.parent = p.parent; if (p.parent == null) root = r; else if (p.parent.left == p) p.parent.left = r; else p.parent.right = r; r.left = p; p.parent = r; } }红黑树 的右旋
p 相当与上图的X.
private void rotateRight(TreeMapEntry<K,V> p) { if (p != null) { TreeMapEntry<K,V> l = p.left; p.left = l.right; if (l.right != null) l.right.parent = p; l.parent = p.parent; if (p.parent == null) root = l; else if (p.parent.right == p) p.parent.right = l; else p.parent.left = l; l.right = p; p.parent = l; } }以上