zoukankan      html  css  js  c++  java
  • TreeMap

    文章开头,全家桶少不了。
    作为HashMap的好兄弟,TreeMap存在肯定是有的他的理由的。
    我看源码喜欢先看JavaDoc
    翻译TreeMap的JavaDoc
    基于红黑树的NavigableMap实现。 根据映射的键的Comparable或根据映射创建时提供的Comparator对映射进行排序,具体取决于所使用的构造函数。
    此实现为containsKey,get,put和remove操作提供了保证的log(n)时间成本。算法是对Cormen,Leiserson和Rivest的<<算法简介>>中的算法的改编。
    请注意,与任何已排序的映射一样,树映射所维护的顺序以及是否提供显式比较器,必须与equals是正确的实现Map接口。具体请参见Comparable或Comparator,以精确了解与equals一致的。之所以这样,是因为Map接口是根据equals操作的,但是排序的映射使用其compareTo或compare方法执行所有键比较,此方法视为相等的两个键是排序后的Map。排序后的映射的行为是明确定义的,即使其顺序与equals不匹配;它只是无法遵守Map接口的一般合同。
    查看TreeMap的继承图
    也就是说所有基本的CRUD操作其实都是和Map一样的,所以就不详细写了,主要还是写一些这个的应用场景以及使用的注意点,以及他的特点。

    首先TreeMap是基于红黑树来实现的,那就顺带复习一下红黑树好了。

    红黑树规则特点:

    1. 节点分为红色或者黑色;
    2. 根节点必为黑色;
    3. 叶子节点都为黑色,且为null;
    4. 连接红色节点的两个子节点都为黑色(红黑树不会出现相邻的红色节点);
    5. 从任意节点出发,到其每个叶子节点的路径中包含相同数量的黑色节点;
    6. 新加入到红黑树的节点为红色节点;

    红黑树自平衡基本操作:

    1. 变色:在不违反上述红黑树规则特点情况下,将红黑树某个node节点颜色由红变黑,或者由黑变红;
    2. 左旋:逆时针旋转两个节点,让一个节点被其右子节点取代,而该节点成为右子节点的左子节点
    3. 右旋:顺时针旋转两个节点,让一个节点被其左子节点取代,而该节点成为左子节点的右子节点

    TreeMap的特点
    • TreeMap实现了NavigableMap接口,而NavigableMap接口继承着SortedMap接口,致使我们的TreeMap是有序的!如果没有实现comparator,默认按照key的自然顺序排序。如果在构造方法中传递了Comparator对象,那么就会按照Comparator的方法进行比较值得说明的是:如果使用的是compareTo(T o)方法来比较,key一定是不能为null,并且得实现了Comparable接口的。即使是传入了Comparator对象,不用compareTo(T o)方法来比较,key也是不能为null的
    • 由于底层是红黑树,那么时间复杂度可以保证为log(n)这个理论的介绍可以看https://blog.csdn.net/JERRY_PRI/article/details/8959426?utm_source=blogxgwz1
    • key不能为null,为null为抛出NullPointException的,但是如果硬要为null就是在构造的时候用自己的Comparator
    • 想要自定义比较,在构造方法中传入Comparator对象,否则使用key的自然排序来进行比较
    • TreeMap非同步的,想要同步可以使用Collections来进行封装

    TreeMap的使用场景
    这其实也认为是红黑树的使用场景
    1. 红黑树是牺牲了严格的高度平衡的优越条件为代价,它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。
    2. 红黑树能够以O(log2 n)的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。当然,还有一些更好的,但实现起来更复杂的数据结构能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。
    3. TreeMap 实现了 SortMap 接口,其能够根据键排序,默认是按键的升序排序,也可以指定排序的比较器,当用 Iterator 遍历 TreeMap 时得到的记录是排过序的,TreeMap 取出来的是排序后的键值
    4.  红黑树占用的内存更小(仅需要为其存在的节点分配内存),而Hash事先应该分配足够的内存存储散列表,即使有些槽可能弃用。

    TreeMap的注意点
    红黑树是以 key 来进行排序的,所以这里以 key 来进行比较检索出合适的叶子结点,而比较多依据就是 Comparator 或者 Comparable ,如果比较出来的结果是 0,那么后面的 value 会覆盖前面的 value。所以在使用 Map 的时候,一定要注意底层的数据结构和对 key 的处理方式。
  • 相关阅读:
    LeetCode
    LeetCode
    ELK系列(5)
    ELK系列(4)
    ELK系列(3)
    ELK系列(2)
    ELK系列(1)
    计算机网络常见面试题总结
    mosquitto启动时Address already in use 和 一般的 Address already in use
    size和STL中的size_type
  • 原文地址:https://www.cnblogs.com/SmartCat994/p/13188027.html
Copyright © 2011-2022 走看看