• 算法导论读书笔记(16)


    算法导论读书笔记(16)

    动态顺序统计

    之前介绍过 顺序统计 的概念。在一个无序的集合中,任意的顺序统计量都可以在 O ( n )时间内找到。而这里我们将介绍如何在 O ( lg n )时间内确定任意的顺序统计量。

    下图显示的是一种支持快速顺序统计量操作的数据结构。一棵 顺序统计树 T 通过在红黑树的每个结点中存入附加信息而成。在一个结点 x 内,增加域 x.size 。该域包含以结点 x 为根的子树的(内部)结点数(包括 x 本身),即子树的大小。设 T.nil.size 为0,则有

    x.size = x.left.size + x.right.size + 1


    检索具有给定排序的元素

    过程 OS-SELECT(x, i) 返回一个指向以 x 为根的子树中包含第 i 小关键字的结点的指针。为找出顺序统计树 T 中的第 i 小关键字,调用过程 OS-SELECT(T.root, i)

    OS-SELECT(x, i)
    1 r = x.left.size + 1
    2 if i == r
    3     return x
    4 elseif i < r
    5     return OS-SELECT(x.left, i)
    6 else
    7     return OS-SELECT(x.right, i)
    

    对含 n 个元素的动态集合, OS-SELECT 的运行时间为 O ( lg n )。

    确定一个元素的秩

    给定指向一顺序统计树 T 中结点 x 的指针,过程 OS-RANK 返回在对 T 进行中序遍历后得到的线性序中 x 的位置。

    OS-RANK(T, x)
    1 r = x.left.size + 1
    2 y = x
    3 while y != T.root
    4     if y == y.p.right
    5         r = r + y.p.left.size + 1
    6     y = y.p
    7 return r
    

    x 的秩可以视为在对树的中序遍历中,排在 x 之前的结点个数再加1( x 本身)。在最坏情况下,对含 n 个结点的顺序统计树, OS-RANK 的运行时间为 O ( lg n )。

    区间树

    在算法设计过程中,经常需要对基本的数据结构进行扩张,以便支持一些新功能。而对一种数据结构的扩张过程通常可以分为四个步骤:

    1. 选择基础数据结构
    2. 确定要在基础数据结构中添加哪些信息
    3. 验证可用基础数据结构上的基本修改操作来维护这些新添加的信息
    4. 设计新的操作

    以上只是给出了一个一般模式,设计顺序统计树时,我们就依照了这些步骤。

    在这里,我们要扩展红黑树以支持由区间构成的动态集合上的操作(假设区间都是闭区间)。一个 闭区间 是一个实数的有序对[ t1, t2 ],其中 t1 <= t2 。我们可以把一个区间[ t1, t2 ]表示成一个对象,其各个域为 i.low = t1 (低端点), i.high = t2 (高端点)。任意两个区间 ii' 都满足 区间三分法 ,即:

    • ii' 重叠( i.low <= i'.high ,且 i'.low <= i.high
    • ii' 左边( i.high < i'.low
    • ii' 右边( i'.high < i.low

    区间树是一种对动态集合进行维护的红黑树,该集合中的每个元素 x 都包含一个区间 x.int 。区间树支持下列操作:

    • INTERVAL-INSERT(t, X) :将包含区间域 int 的元素 x 插入到区间树 T 中。
    • INTERVAL-DELETE(T, x) :从区间树 T 中删除元素 x
    • INTERVAL-SEARCH(T, i) :返回一个指向区间树 T 中元素 x 的指针,使 x.inti 重叠;否则返回 T.nil

    下面就按之前提到的四个步骤,来分析和设计区间树上的各种操作。

    步骤1:基础数据结构

    基础数据结构为红黑树,其中每个结点 x 包含一个区间域 x.intx 的关键字为区间的低端点 x.int.low

    步骤2:附加信息

    每个结点还要包含一个值 x.max ,即以 x 为根的子树中所有区间的端点的最大值。

    步骤3:维护信息

    必须验证对含 n 个结点的区间树的插入和删除能在 O ( lg n )时间内完成。给定区间 x.intx 的子结点的 max 值,可以确定 x.max = max ( x.int.high , x.left.max , x.right.max )。

    步骤4:设计新操作

    唯一需要的新操作是 INTERVAL-SEARCH

    INTERVAL-SEARCH(T, i)
    1 x = T.root
    2 while x != T.nil and i does not overlap x.int
    3     if x.left != T.nil and x.left.max >= i.low
    4         x = x.left
    5     else
    6         x = x.right
    7 return x
    
  • 相关阅读:
    表达式计算 六月飞雪
    code::blocks 单步执行 六月飞雪
    5.1 字符串 六月飞雪
    对使用倒序的一维数组解决0/1背包问题的理解 六月飞雪
    5.2 高精度运算 六月飞雪
    关于ArcEngine“不能再打开其他表了”的错误 (20121026 15:43:33)
    关于AO插入对象
    多线程使用实例
    C#程序运行时间长出现无法响应状态
    Geographic coordinate system和projected coordinate
  • 原文地址:https://www.cnblogs.com/sungoshawk/p/3759986.html
Copyright © 2020-2023  润新知