Page 119 - 《软件学报》2025年第8期
P. 119

3542                                                       软件学报  2025  年第  36  卷第  8  期


                 小键值. 因此, max 和   min  函数可以分别通过递归遍历右、左子树节点实现. list_max 和             list_min  可以很好地模拟
                 这一情况, 只需遍历获得列表最末端、首端的键值即可. 由此, 可分别构建                      list_max 和  list_min  的验证引理集, 如
                 图  11 所示. 引理  1 表示  list_max 可以正确获取列表最末端的键值元素. 引理         2 和引理  3 分别表示   list_max、list_min
                 能够模拟递归向右、左子树查找的过程.

                             引理 1  list_max (lst @ [a]) = a
                                                                               list_max  lst 2
                                                                    list_max
                             引理 2  lst 2  ≠ [] ⟹ list_max (lst 1 @ a # lst 2 ) = list_max lst 2  a
                                                                            lst 1      lst 2
                                                                    list_min
                                                                    list_min  lst 1
                             引理 3  lst 1  ≠ [] ⟹ list_min (lst 1 @ a # lst 2 ) = list_min lst 1

                                             图 11 list_max 和  list_min  的验证引理集

                    定理  3. pred  函数.  invar t ⇒ pred x t = list_pred x (inorder t).
                    pred  函数获取前继元素对应两种情况: 一是左子树不为空时, 获取目标节点左子树中的最大元素; 二是左子树
                 为空时, 自底向上找到第        1  个右子树包含目标节点的祖先节点, 祖先节点对应的元素即为前继元素. 前者依赖于
                 max 函数, 可以用函数    list_max 模拟. 后者的实现需要正确记录祖先节点信息. 在自顶向下的查找过程中, 如果依
                 据查找策略判断得出沿着右边的路径进行查找, 则需记录当前的根节点信息                           (对应记录目标节点的祖先节点信
                 息). 当找到目标节点时, 若其左子树为空, 则最近记录的根节点即为目标节点的前继节点.
                    基于上述分析, 可以构建函数         list_pred  的验证引理集, 如图  12  所示. 引理  4−6  处理边界情况, 即没有前继元素
                 的情况, 引理   4  和引理  5  表示若元素  x 不在列表中, 则无法求得其前继元素; 引理            5  表示列表中最小的元素       (即有
                 序列表的第    1  个元素) 没有前继元素. 引理      7−9  分别模拟目标节点等于、小于和大于当前根节点的情况. 若等于,
                 需要调用函数     link_max 来获取对应左子树中的最大元素, 该元素即为前继元素. 若小于或大于, 则需模拟树中向
                 左或向右递归查找的过程. 对应引理           7−9, 引理  10−12  则分别处理使用归纳法后节点增加的情况.

                        引理 4  sorted (a # lst) ⟹ x < a ⟹ list_pred x (a # lst) = None
                        引理 5  sorted (a # lst) ⟹ list_pred a (a # lst) = None
                        引理 6  sorted (lst @ [a]) ⟹ x > a ⟹ list_pred x (lst @ [a]) = None
                                                                   Some  ( list_max  lst 1  )
                             sorted (lst 1  @ a # lst 2 ) ⟹ lst 1 ≠ [] ⟹
                        引理 7
                              list_pred a (lst 1 @ a # lst 2 ) = Some (list_max lst 1 )
                                                                        x = a
                             sorted (lst 1 @ a # lst 2 ) ⟹ x < a ⟹
                        引理 8
                              list_pred x (lst 1 @ a # lst 2 ) = list_pred x lst 1  list_pred  x  lst 1  a  lst 2
                             sorted (lst 1 @ a # lst 2 ) ⟹ x > a ⟹
                        引理 9
                              list_pred x (lst 1 @ a # lst 2 ) = list_pred x (a # lst 2 )  x < a
                             sorted (a # lst 1 @ b # lst 2 ) ⟹ lst 1 ≠ [] ⟹  list_pred  lst 1
                        引理 10
                              list_pred b (a # lst 1 @ b # lst 2 ) = Some (list_max lst 1 )
                             sorted (a # lst 1 @ b # lst 2 ) ⟹ x < b ⟹              list_pred  lst 2
                        引理 11
                              list_pred x (a # lst 1 @ b # lst 2 ) = list_pred x (a # lst 1 )  x > a
                             sorted (a # lst 1 @ b # lst 2 ) ⟹ x > b ⟹
                        引理 12
                              list_pred x (a # lst 1 @ b # lst 2 ) = list_pred x (b # lst 2 )
                                                 图 12 list_pred  的验证引理集

                    定理  4. sucd  函数.  invar t ⇒ sucd x t = list_sucd x (inorder t).
                    求后继元素的函数       sucd  的实现思路与    pred  类似, 两者互为镜像操作. 函数      sucd  需借助  min  函数并记录左边
                 路径的根节点信息. 由此, 可以构建函数           list_sucd  的验证引理集, 如图  13  所示. 引理  13−15  处理没有后继元素的情
   114   115   116   117   118   119   120   121   122   123   124