TreeSet&从树到红黑树

TreeSet

TreeSet好处

  • 插入的同时就立刻进行排序,只需要设定好比较器,就能按照设定来进行排序,因为他是一个红黑树,树的特征就是拥有排序。同时他是个set,只要比较器认为是同一个,就会被去重。

TreeSet使用的结构

  • 其内部是是用了TreeMap,Set值保存在Map的key中,value存了一个Object,Map中如果Key值相同会被认为是同一个,这样就能够实现数据去重。TreeMap内部维护的是一个红黑树。因为是树状结果,那么其查询效率和插入效率都是log(n),当然对应耗时会因为红黑树平衡调整,会有相应的耗时。
  • TreeSet不是线性安全的,线性安全需要使用ConcurrentSkipListSet。内部是SkipList(跳表)结构实现,在理论=上能够实现O(log(n))时间内完成查找、插入、删除操作。

image

  • 跳表本质是一个链表,只是链表节点中会记录一定跨度后的链表节点地址。

属性变更问题

  • TreeSet可以指定比较器Comparator,可以通过类中继承Comparable来进行比较迭代。但是里面的属性变化了,不会重新出发排序。需要重新插入排序。例如,TreeSet保存的类文件,类中包含一些列表,列表数据组装并且同时插入到TreeSet,正好比较器需要比较列表中元素的属性,这时候,因为列表是一直在变化的。会出现,类文件插入到TreeSet的时候,再变更类文件中列表的属性,是无法触发TreeSet中自动排序的。TreeSet无法判断到其对象变更情况。
  • 解决方法
    • 插入到TreeSet前需要确定类文件属性不再变更。
    • 触发变更的时候,重新将其赋值到TreeMap当中,更新比较。

去重问题

  • 如果比较器中返回为0 ,Set中认为是相等的,会执行去重操作。如果比较器逻辑有问题,可能会触发死循环比较。

比较器效率问题

  • TreeSet是边插入边比较,而Collection.sort函数应用场景是List队列当中,两种都能用比较器来完成操作。
  • TreeSet的底层实现是红黑树,他在创建set的过程中实现排序。Collection.sort是对整个集合进行排序,按理来说使用TreeSet插入集合元素直至建立整个TreeSet过程中实现排序在时间方面要比Collections.sort对整个集合进行排序效率要高很多,因为它在每次搜索要插入的位置时耗费的时间为log(n),n代表的是当前集合的长度,但实验表明使用Collections.sort对集合进行排序时间耗费要少些。

image

  • 原因
    • TreeSet的搜索时间是log(n),明显上是比list有优势的
    • TreeSet在插入的时候需要先创建节点,而List比较并不需要增加额外节点
    • TreeSet基于红黑树,其每次插入都需要检查和维护红黑树平衡,如果失衡会触发红黑树结果调整。

从树到红黑树

  • 红黑树是一种自平衡二叉查找树。红黑树的结构复杂,但它的操作有着良好的最坏情况运行时间,并且在实践中高效:它可以在O(log(n))时间内完成查找,插入和删除,这里的n是树中元素的数目。

  • 树是由多个节点(Node)的集合组成,每个节点又有多个与其关联的子节点(Child Node)。子节点就是直接处于节点之下的节点,而父节点则位于子节点直接关联的上方。树的根指的是一个没有父节点的单独的节点。

  • 树相关的术语

    • 根(Root):树中最顶端的节点,根没有父节点。
    • 子节点(Child):节点所拥有子树的根节点称为该节点的子节点。
    • 父节点(Parent):如果节点拥有子节点,则该节点为子节点的父节点。
    • 兄弟节点(Sibling):与节点拥有相同父节点的节点。
    • 子孙节点(Descendant):节点向下路径上可达的节点。
    • 叶节点(Leaf):没有子节点的节点。
    • 内节点(Internal Node):至少有一个子节点的节点。
    • 度(Degree):节点拥有子树的数量。
    • 边(Edge):两个节点中间的链接。
    • 路径(Path):从节点到子孙节点过程中的边和节点所组成的序列。
    • 层级(Level):根为 Level 0 层,根的子节点为 Level 1 层,以此类推。
    • 高度(Height)/深度(Depth):树中层的数量。比如只有 Level 0,Level 1,Level 2 则高度为 3。
  • 树的性质

    • 只有一个根节点
    • 除了根节点,所有节点都有且只有一个父节点
    • 无环。将任意一个节点作为起始节点,都不存在任何回到该起始阶段的路径。

二叉树

  • 二叉树是一种特殊的树类型,其每个节点最多只能有两个节点。

image

满二叉树

  • 一棵深度为 h,且有 2h - 1 个节点的二叉树称之为满二叉树。

完全二叉树

  • 深度为 h,有 n 个节点的二叉树,当且仅当其每一个节点都与深度为 h 的满二叉树中,序号为 1 至 n 的节点对应时,称之为完全二叉树。

image

二叉查找树

  • 二叉查找树是一种特殊的二叉树,它改善了二叉树节点查找的效率。二叉查找树有以下性质:
    • 其左子树下的每个后代节点的值都小于节点n的值
    • 其右子树下的每个后代节点的值都大于节点n的值

红黑树

  • 红黑树是每个节点都带有颜色属性的二叉查找树,颜色为红色或黑色。红黑树有以下额外要求:
  • 节点是红色或黑色
  • 根是黑色
  • 所有叶子都是黑色(叶子是NIL节点)
  • 每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
  • 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。

image

  • 这些约束确保了红黑树的关键特性:从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这个树大致上是平衡的。因为操作比如插入、删除和查找某个值的最坏情况都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的。
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值