在执行结束操做后,经过比较每一个结点的平衡因子来维持AVL树的平衡html
Comparable<T> comparableElement = (Comparable<T>)element
为何要使用comparable来将element转为相关格式呢?java
涂为红色,有什么变化呢?相较于涂为黑色,黑色结点减小,且其孩子结点为黑色。若是是黑色呢?该树总体黑色结点增多。但问题偏偏就在这里,若是这是一颗单独的树还好说,但若是是某一棵树的子树呢?只有这一部分的黑色结点增长,别的均不变,这直接致使违反了规定。因此,从中也能够看出,对于红黑树,黑色结点的变化是至关慎重的。从规定插入的结点默认为红色也能够看出这点。git
所以,一开始,个人思路是,经过比较全部元素来肯定一个中间大小的数据来做为根。但是,这一实现过程较为麻烦,须要将当前树进行重构。翻了翻书,看到大篇幅的旋转,我就知道应该怎样作了。能够看到,每次旋转,都是由部分到总体,从某一棵失衡的子树开始,再向上旋转,再判断再旋转。因此,这是一个重复的过程,所以,能够用递归实现。代码将较为简单。算法
if (data.compareTo(p.getElement()) < 0) {//向左子树寻找插入位置 p.setLeft(insert(data, p.getLeft())); if (height(p.getLeft()) - height(p.getRight()) == 2) {//插入后计算子树的高度,等于2则须要从新恢复平衡,因为是左边插入,左子树的高度确定大于等于右子树的高度 //判断data是插入点的左孩子仍是右孩子 if (data.compareTo(p.getLeft().getElement()) < 0) { //进行LL旋转 p = singleRotateLeft(p); } else { //进行左右旋转 p = doubleRotateWithLeft(p); } } }
这里是部分代码,所有的有点长,就不进行展现。这里最为关键的就是这行代码“ p.setLeft(insert(data, p.getLeft()));
”也就是重复利用递归的部分,经过代替循环体,咱们直接锁定须要插入的位置,在插入结束后,直接就插入结点的父结点的平衡因子来判断插入是否致使失衡,也就是与2进行判断,若是违规,直接进行旋转。这样一来,在树的底层位置进行旋转,尽量缩小涉及到的范围,也就使得更加便于实现。segmentfault
本章的知识很差理解,尤为是红黑树,涉及了大量的不一样状况,使人头秃,并且网上的知识有漏洞的也不少,继续本身体会。数据结构
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 1/1 | 3/3 | |
第二周 | 409/409 | 1/2 | 5/8 | |
第三周 | 1174/1583 | 1/3 | 10/18 | |
第四周 | 1843/3426 | 2/5 | 10/28 | |
第五周 | 539/3965 | 2/7 | 20/48 | |
第六周 | 965/4936 | 1/8 | 20/68 | |
第七周 | 766/5702 | 1/9 | 20/88 |