• TreeMap相关


     

     

    Map接口

    Map集合的特点

    1.能够存储唯一的列的数据(唯一,不可重复) Set

    2.能够存储可以重复的数据(可重复) List

    3.值的顺序取决于键的顺序

    4.键和值都是可以存储null元素的

    TreeMap

    本质上就是红黑树的实现

    1.每个节点要么是红色,要么是黑色。

    2.根节点必须是黑色

    3.每个叶子节点【NIL】是黑色

    4.每个红色节点的两个子节点必须是黑色

    5.任意节点到每个叶子节点的路径包含相同数量的黑节点

     K key; // key
    V value; // 值
    Entry<K,V> left; // 左子节点
    Entry<K,V> right; // 右子节点
    Entry<K,V> parent; // 父节点
    boolean color = BLACK; // 节点的颜色 默认是黑色

     

    put为例

        public V put(K key, V value) {
           // 将root赋值给局部变量 null
           Entry<K,V> t = root;
           if (t == null) {
               // 初始操作
               // 检查key是否为空
               compare(key, key); // type (and possibly null) check
    // 将要添加的key、 value封装为一个Entry对象 并赋值给root
               root = new Entry<>(key, value, null);
               size = 1;
               modCount++;
               return null;
          }
           int cmp;
           Entry<K,V> parent; // 父节点
           // split comparator and comparable paths
           Comparator<? super K> cpr = comparator; // 获取比较器
           if (cpr != null) {
               // 一直找到插入节点的父节点
               do {
                   // 将root赋值给了parent
                   parent = t;
                   // 和root节点比较值得大小
                   cmp = cpr.compare(key, t.key);
                   if (cmp < 0)
                       // 将父节点的左子节点付给了t
                       t = t.left;
                   else if (cmp > 0)
                       t = t.right; // 将父节点的右节点付给了t
                   else
                       // 直接和父节点的key相等,直接修改值
                       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);
          }
           // t 就是我们要插入节点的父节点 parent
           // 将我们要插入的key value 封装成了一个Entry对象
           Entry<K,V> e = new Entry<>(key, value, parent);
           if (cmp < 0)
               parent.left = e; // 插入的节点在parent节点的左侧
           else
               parent.right = e; // 插入的节点在parent节点的右侧
           fixAfterInsertion(e); // 实现红黑树的平衡
           size++;
           modCount++;
           return null;
      }

     

     

    /** From CLR */
    private void fixAfterInsertion(Entry<K,V> x) {
    // 设置添加节点的颜色为 红色
    x.color = RED;
    // 循环的条件 添加的节点不为空 不是root节点 父节点的颜色为红色
    while (x != null && x != root && x.parent.color == RED) {
    // 父节点是否是 祖父节点的左侧节点
    if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
    // 获取父节点的 兄弟节点 叔叔节点
    Entry<K,V> y = rightOf(parentOf(parentOf(x)));
    if (colorOf(y) == RED) { // 叔叔节点是红色
    // 变色
    setColor(parentOf(x), BLACK); // 设置 父节点的颜色为黑色
    setColor(y, BLACK); // 设置叔叔节点的颜色为 黑色
    setColor(parentOf(parentOf(x)), RED); // 设置 祖父节点的颜色是 红色
    // 将祖父节点设置为 插入节点
    x = parentOf(parentOf(x));
    } else { // 叔叔节点是黑色
    if (x == rightOf(parentOf(x))) {
    // 判断插入节点是否是 父节点的右侧节点
    x = parentOf(x); // 将父节点作为插入节点
    rotateLeft(x); // 左旋
    }
    setColor(parentOf(x), BLACK);
    setColor(parentOf(parentOf(x)), RED);
    rotateRight(parentOf(parentOf(x)));// 右旋
    }
    } else {// 父节点是祖父节点的右侧子节点
    // 获取叔叔节点
    Entry<K,V> y = leftOf(parentOf(parentOf(x)));
    if (colorOf(y) == RED) { // 叔叔节点为红色
    // recolor 变色
    setColor(parentOf(x), BLACK);
    setColor(y, BLACK);
    setColor(parentOf(parentOf(x)), RED);
    x = parentOf(parentOf(x));
    } else {
    // 插入节点在父节点的右侧
    if (x == leftOf(parentOf(x))) {
    x = parentOf(x);
    rotateRight(x); // 右旋
    }
    setColor(parentOf(x), BLACK);
    setColor(parentOf(parentOf(x)), RED);
    rotateLeft(parentOf(parentOf(x))); // 左旋
    }
    }
    }
    // 根节点的颜色为黑色
    root.color = BLACK;
    }

  • 相关阅读:
    iOS NSProgress的使用
    GIT的 .gitignore 配置
    MagicalRecord入门教程
    CoreData的数据存储
    NSLog打印信息的从新设置
    大石头得博客
    exc_bad_access(code=1, address=0x789870)野指针错误
    oc 获取当前设备系统的版本号
    免证书真机调试脚本iphoneentitlements
    支持非arc
  • 原文地址:https://www.cnblogs.com/CCTVCHCH/p/15847412.html
Copyright © 2020-2023  润新知