用循环不变式证明RB-INSERT-FIXUP的正确性
来源:互联网 发布:财务报表分析软件 编辑:程序博客网 时间:2024/06/09 18:00
初始化:在循环的第一次迭代之前,我们从一颗正常的红黑树开始,并新增了一个红色结点z。
这样在调用RB-INSERT-FIXUP之前,有:
a)z是红色结点。
b)如果p[z]是根,则p[z]是黑色。
c)红黑树的性质1)、3)和5)都成立。
但性质2)和4)有可能被违反,但不会同时被违反。
如果性质2)被违反,说明红色的根结点必然是新增的结点z,它是树中唯一的内结点。由于z的父结点和两个子结点都是黑色的哨兵(nil[T]),没有违反性质4)。所以,这种情况下,只违反性质2)
如果性质4)被违反,则由于z的子女是黑色的哨兵,并且这棵树在z新增之前,没有其他性质被违反,所以只可能是z和p[z]都是红结点,因为z不是根结点,因此性质2)一定满足。
保持:在while循环中需要考虑6种情况,但后面3种与前面3种是对称的,所以只讨论前面3种情况:
循环不变式的目标有两个:
(1)保证每一次循环后,性质1)、3)、5)不被违反;
(2)修正对性质4)的违反(当退出循环时,性质4)的违反应该已经被修正)。
在讨论3种情况之前,我们考虑一下在初始化步骤,性质2)被违反的情况,这时,z是红色的根结点,此时其父结点是黑色的哨兵(nil[T]),因此直接退出循环,进入循环终止步骤。这种情况下,显然在退出循环时,循环不变式保持了性质1)、3)和5)。并且性质4)也没有被违反,唯一违反的是性质2)。
情况1):z的叔叔y是红色的
上图,对于情况(a),z是其父结点的右子结点;对于情况(b),z是其父结点的左子结点。 从图中可以看出,在执行第5到第8行之后,性质1)和3)显然被保持,在修改父结点和叔父结点以及祖父结点后,从C出发的黒结点的高度没有变化,性质5)也是被保持。 此外,对于z,因为其父结点被设置为黑色,原来对性质4)的违反得以消除,但因为祖父结点被设置为红色,祖父结点和其父结点是有可能违反性质4)的,在程序的第8行,将新z设置为原来z的祖父节点,该新z的是红色的。 这样在下一轮循环开始之前,有: a)z是红色结点。 b)如果p[z]是根,则p[z]是黑色。 c)红黑树的性质1)、3)和5)都成立。 但性质2)和4)有可能被违反,但不会同时被违反。 如果性质2)被违反,说明红色的根结点必然是新z结点。由于z的父结点和两个子结点都是黑色结点,没有违反性质4)。所以,这种情况下,只违反性质2)。 如果性质4)被违反,则由于新z的子女是黑色的结点,并且旧的z对性质4)的违反已经被修正,所以,只可能是新z和p[新z]都是红结点,因为新z不是根结点,因此性质2)一定满足。 这样我们就证明了,对于情况1)循环不变式的成立。 情况2):z的叔叔y是黑色的,而且z是右孩子 情况3):z的叔叔y是黑色的,而且z是左孩子
如上图,对于情况2),经过左旋后,转换成情况3),对于情况3),修改p[z]和p[p[z]的颜色后,进行了右旋,使得最终p[z]颜色是黑色。 下面来证明对于这两种情况下循环不变式的保持: 首先对于性质1)和3)显然保持,对于性质5),从图中可以看出,经过B结点的路径上的黑色结点个数没有变化,因此也是保持的。 这样在下一轮循环开始之前,有: a)z是红色结点。 b)p[z]是黑色。 c)红黑树的性质1)、3)和5)都成立。 此时对性质4)的违反被修正,因为B取代了C的位置,且颜色都是黑色,不会违反性质4)。 此时性质2)也不会被违反,因为如果p[z]是根,那么因为p[z]是黑色结点,显然满足性质2),如果p[z]不是根结点,那么因为在进入这次循环之前不被违反,因而也不会被违反。 因此红黑树的五个性质全部满足,这样我们就证明了,对于情况2)和3)循环不变式的成立。并且,因为p[z]是黑色,因此当执行完情况3),循环一定终止。 终止:循环结束是因为p[z]是黑色的。(如果z是根,p[z]是黑哨兵nil[T]。)所以,在循环结束时,性质4)是满足的。根据循环不变式,性质1)、3)和5)应该保持,所以唯一可能违反的性质是性质2)。第16行将确保性质2)成立,并且这一操作不会破坏其他红黑树的性质,因此当调用RB-INSERT-FIXUP结束时,所有红黑树的性质都成立。
- 用循环不变式证明RB-INSERT-FIXUP的正确性
- 用循环不变式证明RB-DELETE-FIXUP的正确性
- 用归纳法证明循环不变式的正确性。
- 算法学习二:循环不变式证明算法的正确性
- 用循环不变式证明BINOMIAL-HEAP-UNION(H1, H2)的正确性
- 对算法导论中用循环不变式证明算法正确性的理解
- 对于循环不变式证明的总结
- 循环不变式与lower_bound证明
- 补码正确性的证明
- 插入排序证明引发的对于循环不变式的定义
- krusal算法正确性的证明
- 如何证明程序的正确性?
- 树状数组正确性的证明、、、
- 【笔记】程序正确性的证明
- 证明Fesitel 结构的正确性
- [珠玑之椟]浅谈代码正确性:循环不变式、断言、debug
- [珠玑之椟]浅谈代码正确性:循环不变式、断言、debug
- 证明求解约瑟夫斯问题的二进制左循环算法的正确性
- 【转】 如何提高自己的acm个人能力
- C++中extern“C”含义深层探索
- iPhone开发技巧之环境篇(3)--- Xcode中的帮助文档
- 字符集
- iPhone开发技巧之环境篇(4)--- 配置Xcode的窗口布局
- 用循环不变式证明RB-INSERT-FIXUP的正确性
- Study on Android【二】--ContentProvider数据模型概述
- 红黑树的删除
- iPhone开发技巧之环境篇(5)--- 用Subversion管理iPhone程序
- Android Log Analysis
- linux 简单命令
- Study on Android【三】--Intent消息传递
- 求助MFC 多行编辑框显示数据问题
- Study on Android【四】--显示控件使用