加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

3分钟让你大白:HashMap之红黑树树化进程

发布时间:2019-10-13 08:58:37 所属栏目:建站 来源:追逐仰望星空
导读:01 概述 HashMap是Java措施员行使频率最高的用于映射(键值对)处理赏罚的数据范例。跟着JDK(Java Developmet Kit)版本的更新,JDK1.8对HashMap底层的实现举办了优化,譬喻引入红黑树的数据布局和扩容的优化等。本文首要说明一下HashMap中红黑树树化的进程。 02

我们看balanceInsertion

  1. static <K, V> TreeNode<K, V> balanceInsertion(TreeNode<K, V> root, TreeNode<K, V> x) 
  2.  { 
  3.  // 正如开头所说,新插手树节点默认都是赤色的,不会粉碎树的布局。 
  4.  x.red = true; 
  5.  // 这些变量名不是作者任意界说的都是故意义的。 
  6.  // xp:x parent,代表x的父节点。 
  7.  // xpp:x parent parent,代表x的祖父节点 
  8.  // xppl:x parent parent left,代表x的祖父的左节点。 
  9.  // xppr:x parent parent right,代表x的祖父的右节点。 
  10.  for (TreeNode<K, V> xp, xpp, xppl, xppr;;) 
  11.  { 
  12.  // 假如x的父节点为null声名只有一个节点,该节点为根节点,根节点为玄色,red = false。 
  13.  if ((xp = x.parent) == null) 
  14.  { 
  15.  x.red = false; 
  16.  return x; 
  17.  }  
  18.  // 进入else声名不是根节点。 
  19.  // 假如父节点是玄色,那么大吉大利(今晚吃鸡),赤色的x节点可以直接添加到玄色节点后头,返回根就行了不必要任何多余的操纵。 
  20.  // 假如父节点是赤色的,但祖父节点为空的话也可以直接返回根此时父节点就是根节点,由于根必需是玄色的,添加在后头没有任何题目。 
  21.  else if (!xp.red || (xpp = xp.parent) == null) 
  22.  return root; 
  23.   
  24.  // 一旦我们进入到这里就声名白两件是情 
  25.  // 1.x的父节点xp是赤色的,这样就碰着两个赤色节点相连的题目,以是必需颠末旋转调动。 
  26.  // 2.x的祖父节点xpp不为空。 
  27.   
  28.  // 判定假如父节点是否是祖父节点的左节点 
  29.  if (xp == (xppl = xpp.left)) 
  30.  { 
  31.  // 父节点xp是祖父的左节点xppr 
  32.  // 判定祖父节点的右节点不为空而且是否是赤色的 
  33.  // 此时xpp的阁下节点都是红的,以是直接举办上面所说的第三种调动,将两个子节点酿成玄色,将xpp酿成赤色,然后将赤色节点x顺遂的添加到了xp的后头。 
  34.  // 这里各人有疑问为什么将x = xpp? 
  35.  // 这是因为将xpp酿成赤色往后也许与xpp的父节点产生两个相连赤色节点的斗嘴,这就又组成了第二种旋转调动,以是必需从底向上的举办调动,直到根。 
  36.  // 以是令x = xpp,然后举办下下一层轮回,接着往上走。 
  37.  if ((xppr = xpp.right) != null && xppr.red) 
  38.  { 
  39.  xppr.red = false; 
  40.  xp.red = false; 
  41.  xpp.red = true; 
  42.  x = xpp; 
  43.  } 
  44.  // 进入到这个else内里声名。 
  45.  // 父节点xp是祖父的左节点xppr。 
  46.  // 祖父节点xpp的右节点xppr是玄色节点可能为空,默认划定空节点也是玄色的。 
  47.  // 下面要判定x是xp的左节点照旧右节点。 
  48.  else 
  49.  { 
  50.  // x是xp的右节点,此时的布局是:xpp左->xp右->x。这明明是第二中调动必要举办两次旋转,这里先举办一次旋转。 
  51.  // 下面是第一次旋转。 
  52.  if (x == xp.right) 
  53.  { 
  54.  root = rotateLeft(root, x = xp); 
  55.  xpp = (xp = x.parent) == null ? null : xp.parent; 
  56.  } 
  57.  // 针对自己就是xpp左->xp左->x的布局可能因为上面的旋转造成的这种布局举办一次旋转。 
  58.  if (xp != null) 
  59.  { 
  60.  xp.red = false; 
  61.  if (xpp != null) 
  62.  { 
  63.  xpp.red = true; 
  64.  root = rotateRight(root, xpp); 
  65.  } 
  66.  } 
  67.  } 
  68.  }  
  69.  // 这里的说明方法和前面的相对称只不外所有在右测不再一再说明。 
  70.  else 
  71.  { 
  72.  if (xppl != null && xppl.red) 
  73.  { 
  74.  xppl.red = false; 
  75.  xp.red = false; 
  76.  xpp.red = true; 
  77.  x = xpp; 
  78.  } else 
  79.  { 
  80.  if (x == xp.left) 
  81.  { 
  82.  root = rotateRight(root, x = xp); 
  83.  xpp = (xp = x.parent) == null ? null : xp.parent; 
  84.  } 
  85.  if (xp != null) 
  86.  { 
  87.  xp.red = false; 
  88.  if (xpp != null) 
  89.  { 
  90.  xpp.red = true; 
  91.  root = rotateLeft(root, xpp); 
  92.  } 
  93.  } 
  94.  } 
  95.  } 
  96.  } 
  97.  } 

假如您的遐想手段很强的话预计到这里应该已司领略这齐集调动的首要的相关。

下面简述一下前面的两各种荣幸的环境

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读