TreeMap相关详解

来源:互联网 发布:淘宝如何设置包邮 编辑:程序博客网 时间:2024/05/19 16:20

如果只需要存储功能,使用HashMap与LinkedHashMap是一种更好的选择;如果还需要保证统计性能或者需要对Key按照一定规则进行排序,那么使用TreeMap是一种更好的选择。

红黑树是为了维护二叉查找树的平衡而产生的一种树

  1. 根节点与叶节点都是黑色节点,其中叶节点为Null节点
  2. 每个红色节点的两个子节点都是黑色节点,换句话说就是不能有连续两个红色节点
  3. 从根节点到所有叶子节点上的黑色节点数量是相同的

TreeMap KEY不能为NULL VALUE可以为NULL
TreeMap KEY重复覆盖 VALUE可以为重复
TreeMap 按照自然顺序排序 或者按照算法排序
TreeMap 非线程安全

TreeMap
基于红黑树实现

  1. 父节点引用
  2. 左子节点引用
  3. 右子节点引用
  4. 节点颜色
static final class Entry<K,V> implements Map.Entry<K,V> {        K key;        V value;        Entry<K,V> left = null;        Entry<K,V> right = null;        Entry<K,V> parent;        boolean color = BLACK;        ...}

  1. 获取根节点,根节点为空,产生一个根节点,将其着色为黑色,退出余下流程
  2. 获取比较器,如果传入的Comparator接口不为空,使用传入的Comparator接口实现类进行比较;如果传入的Comparator接口为空,将Key强转为Comparable接口进行比较
  3. 从根节点开始逐一依照规定的排序算法进行比较,取比较值cmp,如果cmp=0,表示插入的Key已存在;如果cmp>0,取当前节点的右子节点;如果cmp<0,取当前节点的左子节点
  4. 排除插入的Key已存在的情况,第(3)步的比较一直比较到当前节点t的左子节点或右子节点为null,此时t就是我们寻找到的节点,cmp>0则准备往t的右子节点插入新节点,cmp<0则准备往t的左子节点插入新节点
  5. new出一个新节点,默认为黑色,根据cmp的值向t的左边或者右边进行插入
  6. 插入之后进行修复,包括左旋、右旋、重新着色这些操作,让树保持平衡性

举个栗子,
首先放(10,”10”)
首先是put(10, “10”),由于此时TreeMap中没有任何节点,因此10为根且根节点为黑色节点
接着是put(85, “85”),这一步也不难,85比10大,因此在10的右节点上,但是由于85不是根节点,因此会执行fixAfterInsertion方法进行数据修正
默认插入的节点必须是红色的,以此来维持红黑树的性质(3)
当然插入节点着色为红色节点后,有可能导致的问题是违反性质(2),即出现连续两个红色节点,这就需要通过旋转操作去改变树的结构,解决这个问题。

原创粉丝点击