File tree Expand file tree Collapse file tree 1 file changed +3
-3
lines changed
2015/01/15/2015-01-15-180658 Expand file tree Collapse file tree 1 file changed +3
-3
lines changed Original file line number Diff line number Diff line change @@ -207,13 +207,13 @@ <h2 id="红黑树的介绍">红黑树的介绍</h2>
207207< blockquote >
208208< p > 1)每个结点要么是红的,要么是黑的。< br > 2)根结点是黑的。< br > 3)每个叶结点,即空结点(NIL)是黑的。< br > 4)如果一个结点是红的,那么它的俩个儿子都是黑的。< br > 5)对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。</ p >
209209</ blockquote >
210- < p > < img src ="http://whj-img.qiniudn.com/红黑树结构.png " alt ="红黑树构造图 "> < br > 上文中我们所说的< strong > 叶结点</ strong > 或< strong > NULL结点</ strong > ,如上图所示,它不包含数据而只充当树在此结束的指示,这些节点在绘图中经常被省略。
210+ < p > < img src ="http://whj-img.qiniudn.com/红黑树结构.png " alt ="红黑树构造图 "> < br > 上文中我们所说的< strong > 叶结点</ strong > 或< strong > NULL结点</ strong > ,如上图所示,它不包含数据而只充当树在此结束的指示,这些节点在绘图中经常被省略。
211211 </ p >
212212< h2 id ="红黑树的旋转 "> 红黑树的旋转</ h2 >
213- < p > 当对红黑树执行插入和删除等操作时,对树作修改可能会破坏红黑树的性质。为了继续保持红黑树的性质,可以通过对结点进行重新着色,以及对树进行相关的旋转操作,即通过修改树中某些结点的颜色及指针结构,来达到对红黑树进行插入或删除结点等操作后继续保持它的性质或平衡的目的。< br > 树的旋转分为左旋和右旋,下面借助图来介绍一下左旋和右旋这两种操作。首先,介绍左旋操作。< br > < img src ="http://whj-img.qiniudn.com/红黑树左旋.png " alt ="红黑树的左旋 "> < br > 如上图所示,当在某个结点pivot上,做左旋操作时,我们假设它的右孩子Y不是NIL,pivot可以为任何不是NIL的结点。左旋使Y成为该子树的新根,而Y的左孩子b则成为pivot的右孩子。</ p >
213+ < p > 当对红黑树执行插入和删除等操作时,对树作修改可能会破坏红黑树的性质。为了继续保持红黑树的性质,可以通过对结点进行重新着色,以及对树进行相关的旋转操作,即通过修改树中某些结点的颜色及指针结构,来达到对红黑树进行插入或删除结点等操作后继续保持它的性质或平衡的目的。< br > 树的旋转分为左旋和右旋,下面借助图来介绍一下左旋和右旋这两种操作。首先,介绍左旋操作。< br > < img src ="http://whj-img.qiniudn.com/红黑树左旋.png " alt ="红黑树的左旋 "> < br > 如上图所示,当在某个结点pivot上,做左旋操作时,我们假设它的右孩子Y不是NIL,pivot可以为任何不是NIL的结点。左旋使Y成为该子树的新根,而Y的左孩子b则成为pivot的右孩子。</ p >
214214< figure class ="highlight "> < table > < tr > < td class ="gutter "> < pre > < div class ="line "> 1</ div > < div class ="line "> 2</ div > < div class ="line "> 3</ div > < div class ="line "> 4</ div > < div class ="line "> 5</ div > < div class ="line "> 6</ div > < div class ="line "> 7</ div > < div class ="line "> 8</ div > < div class ="line "> 9</ div > < div class ="line "> 10</ div > < div class ="line "> 11</ div > < div class ="line "> 12</ div > < div class ="line "> 13</ div > </ pre > </ td > < td class ="code "> < pre > < div class ="line "> < span class ="type "> LeftRoate</ span > (< span class ="type "> T</ span > , x) </ div > < div class ="line "> y ← x.< span class ="keyword "> right</ span > < span class ="comment "> //y指向x的右孩子 </ span > </ div > < div class ="line "> x.< span class ="keyword "> right</ span > ← y.< span class ="keyword "> left</ span > < span class ="comment "> //y的左孩子成为x的右孩子 </ span > </ div > < div class ="line "> < span class ="keyword "> if</ span > y.< span class ="keyword "> left</ span > ≠ < span class ="type "> T</ span > .< span class ="built_in "> nil</ span > < span class ="comment "> //y的左孩子不为空,则将其父设置为x</ span > </ div > < div class ="line "> y.< span class ="keyword "> left</ span > .p ← x </ div > < div class ="line "> y.p ← x.p < span class ="comment "> //y代替x成为该子树的根结点 </ span > </ div > < div class ="line "> < span class ="keyword "> if</ span > x.p = < span class ="type "> T</ span > .< span class ="built_in "> nil</ span > < span class ="comment "> //若x为根节点将y设置为根节点</ span > </ div > < div class ="line "> < span class ="type "> T</ span > .root ← y </ div > < div class ="line "> elseif x = x.p.< span class ="keyword "> left</ span > < span class ="comment "> //y替换x后将其与上层结点链接,区分x是x.p的左还是右孩子</ span > </ div > < div class ="line "> x.p.< span class ="keyword "> left</ span > ← y </ div > < div class ="line "> < span class ="keyword "> else</ span > x.p.< span class ="keyword "> right</ span > ← y </ div > < div class ="line "> y.< span class ="keyword "> left</ span > ← x < span class ="comment "> //x作为y的左孩子 </ span > </ div > < div class ="line "> x.p ← y</ div > </ pre > </ td > </ tr > </ table > </ figure >
215215
216- < p > 上述程序中,x代表结点类,其数据域中应该有left(左子指针)、right(右子指针)、p(父结点指针)、key(键值)。< br > 下面要介绍的是右旋,其实看示意图我们就可以看出,右旋和左旋是一个对称的关系。< br > < img src ="http://whj-img.qiniudn.com/红黑树左旋.png " alt ="红黑树的右旋 "> < br > 如上图所示,当在某个结点pivot上,做右旋操作时,我们假设它的左孩子y不是NIL,pivot可以为任何不是NIL的结点。左旋使Y成为该子树的新根,而Y的右孩子c则成为pivot的左孩子。</ p >
216+ < p > 上述程序中,x代表结点类,其数据域中应该有left(左子指针)、right(右子指针)、p(父结点指针)、key(键值)。< br > 下面要介绍的是右旋,其实看示意图我们就可以看出,右旋和左旋是一个对称的关系。< br > < img src ="http://whj-img.qiniudn.com/红黑树左旋.png " alt ="红黑树的右旋 "> < br > 如上图所示,当在某个结点pivot上,做右旋操作时,我们假设它的左孩子y不是NIL,pivot可以为任何不是NIL的结点。左旋使Y成为该子树的新根,而Y的右孩子c则成为pivot的左孩子。</ p >
217217< figure class ="highlight "> < table > < tr > < td class ="gutter "> < pre > < div class ="line "> 1</ div > < div class ="line "> 2</ div > < div class ="line "> 3</ div > < div class ="line "> 4</ div > < div class ="line "> 5</ div > < div class ="line "> 6</ div > < div class ="line "> 7</ div > < div class ="line "> 8</ div > < div class ="line "> 9</ div > < div class ="line "> 10</ div > < div class ="line "> 11</ div > < div class ="line "> 12</ div > < div class ="line "> 13</ div > </ pre > </ td > < td class ="code "> < pre > < div class ="line "> < span class ="type "> RightRoate</ span > (< span class ="type "> T</ span > , x) </ div > < div class ="line "> y ← x.< span class ="keyword "> left</ span > < span class ="comment "> //y指向x的左孩子 </ span > </ div > < div class ="line "> x.< span class ="keyword "> left</ span > ← y.< span class ="keyword "> right</ span > < span class ="comment "> //y的右孩子成为x的左孩子 </ span > </ div > < div class ="line "> < span class ="keyword "> if</ span > y.< span class ="keyword "> right</ span > ≠ < span class ="type "> T</ span > .< span class ="built_in "> nil</ span > < span class ="comment "> //y的右孩子不为空,则将其父设置为x</ span > </ div > < div class ="line "> y.< span class ="keyword "> left</ span > .p ← x </ div > < div class ="line "> y.p ← x.p < span class ="comment "> //y代替x成为该子树的根结点 </ span > </ div > < div class ="line "> < span class ="keyword "> if</ span > x.p = < span class ="type "> T</ span > .< span class ="built_in "> nil</ span > < span class ="comment "> //若x为根节点将y设置为根节点</ span > </ div > < div class ="line "> < span class ="type "> T</ span > .root ← y </ div > < div class ="line "> elseif x = x.p.< span class ="keyword "> left</ span > < span class ="comment "> //y替换x后将其与上层结点链接,区分x是x.p的左还是右孩子</ span > </ div > < div class ="line "> x.p.< span class ="keyword "> left</ span > ← y </ div > < div class ="line "> < span class ="keyword "> else</ span > x.p.< span class ="keyword "> right</ span > ← y </ div > < div class ="line "> y.< span class ="keyword "> right</ span > ← x < span class ="comment "> //x作为y的右孩子 </ span > </ div > < div class ="line "> x.p ← y</ div > </ pre > </ td > </ tr > </ table > </ figure >
218218
219219< p > 我们从上面的解释上可以看到:树在经过左旋右旋之后,二叉搜索的性质保持不变,但红黑性质则被破坏了,所以,红黑树插入和删除数据后,需要结合旋转与颜色重涂来重新恢复树的红黑性质。</ p >
You can’t perform that action at this time.
0 commit comments