思路:树 —— 二叉树 —— 平衡二叉树 —— 红黑树算法
在讲红黑树以前咱们的先明白什么是树?树是一种经常使用的数据结构,它是一个由有限节点组成的一个具备层次关系的集合,数据就存在树的这些节点中。数据结构
最顶层只有一个节点,称为根节点(root)。源码分析
在分支出有一个节点,指向多个方向,若是某个节点下方没有任何分叉的话,那么这个节点就称为叶子节点。性能
从某节点出发,到叶子节点为止,最长简单路径上边的条数,称为该节点的高度。spa
从根节点出发,到某节点边的条数,称为该节点的深度。blog
如图1-1所示的树,根节点root的深度为0,高度为2;节点3的深度为1,高度为1排序
树结构的特色:(1)一个节点,即只有根节点,也能够是一棵树继承
(2)其中任何一个几点与下面全部节点构成的树称为子树递归
(3)根节点没有父节点,而叶子节点没有子节点源码
(4)除跟节点外,任何节点有且仅有一个父节点
(5)任何节点能够有0~n个子节点
二叉树顾名思义就是每一个节点至多有两个子节点的树称为二叉树。图1-1正好就是一棵二叉树。二叉树是一种经典的数据结构,近似与二分法的一种数据结构实现,是高效算法实现的载体。而平衡二叉树、二叉查找树、红黑树则是二叉树中最为重要的概念。试想一下,若是一个二叉树只有一条分支它还叫二叉树吗?
是的,它仍是一个二叉树(图1-2 a)。只不过它只是以“树”之名,行“链表”之实,彻底忽视了二叉树的优势以及高效。因此咱们为了尽量的展示二叉树的优点还须要对二叉树作一些约束。这就衍生出了平衡二叉树的概念。
高度差是平衡一棵树是否为平衡二叉树的决定条件。
平衡二叉树的性质:(1)树的左右高度差不能超过1
(2)任何往下递归的左子树与右子树,必须符合第一条性质
(3)没有任何节点或只有根节点的树也是平衡二叉树
在平衡二叉树的基础上再增长一个条件:对于任何节点而言,它的左子树上全部节点的值都小于它,它右子树上全部节点的值都大于他。这样就产生了更为经典的二叉查找树,这种树最大的优势就是查找数据很是快且数据有序,由于它只须要少数几回的值比较就能够找到须要的数据节点。可是这又带来另外一个问题,那就是遍历节点。
遍历节点有三种经常使用方式:前序、中序、后序。他们的规律:(1)在任何递归子树中,左节点必定在右节点以前遍历
(2)前序、中序、后序仅仅指节点在遍历是的位置顺序
前序遍历的顺序:根节点——左节点——右节点
中序遍历的顺序:左节点——根节点——右节点
后序遍历的顺序:左节点——右节点——根节点
用图1-2 b举例,中序遍历:6-7-8-9-10-11
咱们已经知道二叉查找树是一种平衡树,可是随着数据的插入咱们怎么保证二叉树的平衡性呢?这就引入了 旋转 的操做,旋转又分为左旋和右旋。
右旋:以某个节点为中心,将它沉入它的右子节点,让它的左子节点上升为新树的根节点(顶替本身下沉前的位置),上升前的右子节点变为下沉后的左子节点。
左旋:同理,以某个节点为中心,将它沉入它的左子节点,让它的右子节点上升为新树的根节点(顶替本身下沉前的位置),上升前的左子节点变为下沉后的右子节点。
经过左旋和右旋可使不平衡的二叉树恢复平衡性。最为直观的就是AVL树,AVL树就是经过不断的旋转来达到树的平衡的,AVL树的平衡要求是全部递归子树的高度差不能超过1,也就是说有递归子树的高度差超过1就会出发AVL树的旋转操做。AVL是的性质形成了它的平衡性极好,查找数据效率高,可是却牺牲了必定的增删性能。但在实际生产过程咱们有不少场景会涉及大量的增删操做,若是使用AVL树其实并不那么理想,由此,咱们能够选择红黑树。
红黑树本质上也是一种二叉平衡树,增长了着色的操做,它相比于平衡二叉树多了5个约束:
(1)节点只能是红色和黑色
(2)根节点只能是黑色
(3)全部NIL节点都是黑色
(4)一条路径上不能出现相邻的两个红色节点
(5)在任何递归子树内,根节点到叶子节点全部路径上包含相同数目的黑色节点
注:NIL节点即Nothing In Leaf,在叶子节点上不存在的两个虚拟节点
红黑树追求的是一种大体的平衡,它不像AVL树那样保证任何递归子树的高度差不超过1,它保证的是从根节点到叶子节点的最长路径不超过最短路径的2倍
红黑树经过从新着色和左右旋转维持平衡性。在插入时,红黑树和AVL树都能在至多2次旋转内恢复平衡,但在删除时,AVL树可能至多须要O(log n)次的旋转才能恢复平衡,红黑树至多3次旋转就能恢复平衡,这是因为红黑树维持的是一种大体的平衡。
红黑树适合用于增删操做频繁的场景,这与AVL树偏偏相反,AVL则适合遍历操做频繁的场景。
1.介绍
TreeMap是一个Map集合类,内部按照Key排序来组织内部结构,不一样于通常的Map类,TreeMap是一个有序集合。
2.特色
TreeMap和HashMap同样也继承了AbstractMap抽象类,此外,还继承了NavigableMap和SortedMap。继承SortedMap就表示它的Key是有序不可重复的,Key必须实现Comparable或提供额外的比较器Comparator,因此Key不容许为null,但Value能够为null。TreeMap中Key的去重并不是是覆写HashCode和equals方法来实现的,而是经过Comparable或Comparator来实现的。TreeMap中同时存在Comparable和Comparator会优先使用Compatator。
3.源码分析
4.TreeMap与HashMap