HashMap read an article in a red-black tree implementation principle

Foreword

In this paper we look at the design of a red-black tree, HashMap terms compared to jdk1.7, jdk1.8 most important is the introduction of design red-black tree, when the chain length of the conflict over 8, when the list structure will turned red-black tree structure.

01 cause, story

" JDK1.8 most important is the introduction of design-black tree (when the length of the list of conflicts over eight time), why this design? Benefit is to avoid the most extreme case of conflict becomes a long, long list long, at query time, efficiency will be very slow.


HashMap read an article in a red-black tree implementation principle



  • Red-black tree query: its access performance similar to a binary search, the time complexity of O (logn);

  • Query list: In this case, all the elements need to traverse the job, the time complexity of O (n);

This article is to explain the red-black tree realize that only by fully understanding the red-black tree, for previous analysis will be more understanding.

" Simply put, red-black tree is an approximately balanced binary search tree, its main advantage is" balanced ", ie left and right subtrees almost the same height, in order to prevent degradation of the tree as a list, by this way Find guarantee the time complexity of log (n).

HashMap read an article in a red-black tree implementation principle


Red-black tree on content, online content given very much, mainly in the following characteristics:

  • 1, each node is either red or black, but the root is always black;

  • 2, each of the two child nodes of a certain node are black red;

  • 3, red node can not be continuous (ie, the red node of children and the father can not be red);

  • 4, a path from any node to each of its sub-tree leaf node contains the same number of black nodes;

  • 5, all of the leaf nodes are black (note here that in fact the figure above the leaf node NIL node);

When the tree structure is changed (insertion or deletion), tend to disrupt the condition 3 or condition 4 above, must be adjusted so that the search tree again satisfy the conditions of the red-black tree.

02, adjust the way

" As already when it comes to tree structural changes, the red-black tree condition may be damaged, it must be adjusted so that the search tree again to meet the conditions of the red-black tree.

调整可以分为两类:一类是颜色调整,即改变某个节点的颜色,这种比较简单,直接将节点颜色进行转换即可;另一类是结构调整,改变检索树的结构关系。结构调整主要包含两个基本操作:左旋(Rotate Left),右旋(RotateRight)

2.1、左旋

左旋的过程是将 p 的右子树绕 p 逆时针旋转,使得 p 的右子树成为 p 的父亲,同时修改相关节点的引用,使左子树的深度加 1,右子树的深度减 1,通过这种做法来调整树的稳定性。过程如下:

HashMap read an article in a red-black tree implementation principle



以 jdk1.8 为例,打开 HashMap 的源码部分,红黑树内部类 TreeNode 属性分析:

static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
		//指向父节点的指针
		TreeNode<K,V> parent;
		//指向左孩子的指针
 TreeNode<K,V> left;
		//指向右孩子的指针
 TreeNode<K,V> right;
		//前驱指针,跟next属性相反的指向
 TreeNode<K,V> prev;
		//是否为红色节点
 boolean red;
		......
}

左旋方法 rotateLeft 如下:

/*
 * 左旋逻辑
 */
static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root,
 TreeNode<K,V> p) {
			//root:表示根节点
			//p:表示要调整的节点
			//r:表示p的右节点
			//pp:表示p的parent节点
			//rl:表示p的右孩子的左孩子节点
 TreeNode<K,V> r, pp, rl;
			//r判断,如果r为空则旋转没有意义
 if (p != null && (r = p.right) != null) {
				//多个等号的连接操作从右往左看,设置rl的父亲为p
 if ((rl = p.right = r.left) != null)
 rl.parent = p;
				//判断p的父亲,为空,为根节点,根节点的话就设置为黑色
 if ((pp = r.parent = p.parent) == null)
 (root = r).red = false;
				//判断p节点是左儿子还是右儿子
 else if (pp.left == p)
 pp.left = r;
 else
 pp.right = r;
 r.left = p;
 p.parent = r;
 }
 return root;
}

2.2、右旋

了解了左旋转之后,相应的就会有右旋,逻辑基本也是一样,只是方向变了。右旋的过程是将 p 的左子树绕 p 顺时针旋转,使得 p 的左子树成为 p 的父亲,同时修改相关节点的引用,使右子树的深度加 1,左子树的深度减 1,通过这种做法来调整树的稳定性。实现过程如下:


HashMap read an article in a red-black tree implementation principle


同样的,右旋方法 rotateRight 如下:

/*
 * 右旋逻辑
 */
static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root,
 TreeNode<K,V> p) {
			//root:表示根节点
			//p:表示要调整的节点
			//l:表示p的左节点
			//pp:表示p的parent节点
			//lr:表示p的左孩子的右孩子节点
 TreeNode<K,V> l, pp, lr;
			//l判断,如果l为空则旋转没有意义
 if (p != null && (l = p.left) != null) {
				//多个等号的连接操作从右往左看,设置lr的父亲为p
 if ((lr = p.left = l.right) != null)
 lr.parent = p;
				//判断p的父亲,为空,为根节点,根节点的话就设置为黑色
 if ((pp = l.parent = p.parent) == null)
 (root = l).red = false;
				//判断p节点是右儿子还是左儿子
 else if (pp.right == p)
 pp.right = l;
 else
 pp.left = l;
 l.right = p;
 p.parent = l;
 }
 return root;
}

03, an example for the operation

3.1, the insert adjustment process illustrated

HashMap read an article in a red-black tree implementation principle



3.2, delete the adjustment process diagram

HashMap read an article in a red-black tree implementation principle


3.3, query process diagram

HashMap read an article in a red-black tree implementation principle


04, summary

Thus, to achieve red-black tree is basically completed, on red-black tree structure, there are many cases, the situation is more complicated, but the overall adjustment process, basically to adjust the structure and then adjust the color, until finally meet red-black tree property requirements so far.


Guess you like

Origin blog.51cto.com/14455981/2442655