算法导论 第二十章 van Emde Boas树

动态集合应当支持的操作有:SEARCH,INSERT,DELETE,MINIMUM,MAXIMUM,SUCCESSOR,PREDECESSOR,MEMBER。

20.1基本方法

直接寻址:采用位向量方法,利用u个位来表示域[0~u-1]中的所有数。INSERT,DELETE,MEMBER的运行时间为O(1),但是其他操作的运行时间为theta(u)。

叠加的二叉树结构:数组为也节点(假设为2^n次个位),两两取或向上生成中间节点,直到根节点(2^0),高度为n。结构如下图

两两取或向上生成中间节点这个操作保证在节点的子树中保证存在有一个节点,所有操作最多需要向上到根再向下到叶子节点来维护这个性质复杂度为O(lgu)。

叠加的一棵高度恒定的树:设u=2^(2k), 则u的平方根su=2^k,若我们用一棵度为su的树来代替二叉树,则按su个向上取或得到上一层元素。如下图:


也可以假设由根节点出发,下一层的元素个数为su,再下一层的个数为su^2 = (2^k)^2 = 2^(2k) = u。

去掉根节点把上一层的元素都放到一个大小为2^(k-1)名为summary的数组里边则可以得到如下结构:


则可以将su变为算法复杂度的乘数,并降低树的高度为常数,从而使得算法复杂度变为O(su)。


20.2 递归结构

若要把上图表示在一个结构中,我们可以定义如下结构:



并实现所有这些操作:

import math

def high(x, u):
    return math.floor(x/math.sqrt(u))

def low(x,u):
    return x%math.sqrt(u)

def index(x,y,u):
    return x*math.sqrt(u) + y

class proto_vEB():
    def __init__(self, u):
        self.u = u
        self.summary = None
        self.cluster = None
        self.A = None
        self.n = 0

def PROTO_vEB_CREATE(u):
    node = proto_vEB(u)
    if u == 2:
        node.A = [0,0]
    else:
        su = int(math.sqrt(u));
        node.summary = PROTO_vEB_CREATE(su)
        node.cluster = [PROTO_vEB_CREATE(su) for i in range(su)]

    return node

def PROTO_vEB_MEMBER(V, x):
    if V.u == 2:
        return V.A[int(x)]
    else:
        return PROTO_vEB_MEMBER(V.cluster[high(x, V.u)], low(x,V.u))

def PROTO_vEB_INSERT(V, x):
    V.n = V.n + 1
    if V.u == 2:
        V.A[int(x)] = 1
    else:
        PROTO_vEB_INSERT(V.cluster[high(x, V.u)], low(x,V.u))
        PROTO_vEB_INSERT(V.summary, high(x,V.u))

def PROTO_vEB_DELETE(V, x):
    V.n = V.n - 1
    if V.u == 2:
        V.A[int(x)] = 0
    else:
        PROTO_vEB_DELETE(V.cluster[high(x, V.u)], low(x,V.u))
        if V.cluster[high(x, V.u)].n == 0:
            PROTO_vEB_DELETE(V.summary, high(x,V.u))
        

def PROTO_vEB_MINIMUM(V):
    if V.u == 2:
        if V.A[0] == 1:
            return 0
        elif V.A[1] == 1:
            return 1
        else:
            return None
    else:
        min_cluster = PROTO_vEB_MINIMUM(V.summary)
        if min_cluster == None:
            return None
        else:
            offset = PROTO_vEB_MINIMUM(V.cluster[int(min_cluster)])
            return index(min_cluster, offset, V.u)

def PROTO_vEB_MAXIMUM(V):
    if V.u == 2:
        if V.A[1] == 1:
            return 1
        elif V.A[0] == 1:
            return 0
        else:
            return None
    else:
        max_cluster = PROTO_vEB_MAXIMUM(V.summary)
        if max_cluster == None:
            return None
        else:
            offset = PROTO_vEB_MAXIMUM(V.cluster[int(max_cluster)])
            return index(max_cluster, offset, V.u)

def PROTO_vEB_SUCCESSOR(V, x):
    if V.u == 2:
        if x == 0 and V.A[1] == 1:
            return 1
        else:
            return None
    else:
        offset = PROTO_vEB_SUCCESSOR(V.cluster[high(x, V.u)], low(x,V.u))
        if offset != None:
            return index(high(x, V.u), offset, V.u)
        else:
            succ_cluster = PROTO_vEB_SUCCESSOR(V.summary, high(x,V.u))
            if succ_cluster == None:
                return None
            else:
                offset = PROTO_vEB_MAXIMUM(V.cluster[int(succ_cluster)])
                return index(succ_cluster, offset, V.u)

def PROTO_vEB_PREDECESSOR(V, x):
    if V.u == 2:
        if x == 1 and V.A[0] == 1:
            return 0
        else:
            return None
    else:
        offset = PROTO_vEB_PREDECESSOR(V.cluster[high(x, V.u)], low(x,V.u))
        if offset != None:
            return index(high(x, V.u), offset, V.u)
        else:
            presucc_cluster = PROTO_vEB_PREDECESSOR(V.summary, high(x,V.u))
            if presucc_cluster == None:
                return None
            else:
                offset = PROTO_vEB_MAXIMUM(V.cluster[int(presucc_cluster)])
                return index(presucc_cluster, offset, V.u)

if __name__ == "__main__":
    V = PROTO_vEB_CREATE(16)

    print(PROTO_vEB_MEMBER(V, 1))
    
    PROTO_vEB_INSERT(V, 3)
    PROTO_vEB_INSERT(V, 1)
    PROTO_vEB_INSERT(V, 2)
    print(PROTO_vEB_MEMBER(V, 1))
    
    print(PROTO_vEB_MAXIMUM(V))
    PROTO_vEB_DELETE(V, 2)
    print(PROTO_vEB_MINIMUM(V))
    print(PROTO_vEB_MAXIMUM(V))
    print(PROTO_vEB_SUCCESSOR(V, 0))
    print(PROTO_vEB_PREDECESSOR(V, 3))
    
这里所有使用递归结构的算法复杂度分析可以回顾递归式替换法求解。求得MEMBER的算法复杂度为O(lg(lgn)).MINIMUM,MAXIMUM,INSERT,DELETE算法复杂度为O(lgn)SUCCESSOR,PREDECESSOR的算法复杂度为O(lgn(lg(lgn)))。

20.3 van Emde Boas树及其操作

观察proto_veb的操作MINIMUM,MAXIMUM的操作若可以在常数时间内完成则效率完全可以提高到lglgn,所以我们增加node的min,max属性,并通过公式去掉u必须为2的整数次幂的限制,得到如下的数据结构


并根据这个结构编写操作函数

import math

def sqrt_up(u):
    return math.pow(2, math.ceil(math.log2(u)/2))

def sqrt_down(u):
    return math.pow(2, math.floor(math.log2(u)/2))

def high(x, u):
    return math.floor(x/sqrt_down(u))

def low(x,u):
    return x%sqrt_down(u)

def index(x,y,u):
    return x*sqrt_down(u) + y

class vEB():
    def __init__(self, u):
        self.u = u
        self.summary = None
        self.cluster = None
        self.min = None
        self.max = None


def vEB_TREE_CREATE(u):
    node = vEB(u)
    if u != 2:
        node.summary = vEB_TREE_CREATE(int(sqrt_up(u)))
        node.cluster = [vEB_TREE_CREATE(int(sqrt_down(u))) for i in range(int(sqrt_up(u)))]

    return node


def vEB_TREE_MINIMUM(V):
    return V.min

def vEB_TREE_MAXIMUM(V):
    return V.max

def vEB_TREE_MEMBER(V, x):
    if x == V.min or x == V.max:
        return True
    elif V.u == 2:
        return False
    else:
        return vEB_TREE_MEMBER(V.cluster[high(x, V.u)], low(x,V.u))

def vEB_TREE_SUCCESSOR(V, x):
    if V.u == 2:
        if x== 0 and V.max == 1:
            return 1
        else:
            return None
    elif V.min != None and x < V.min:
        return V.min
    else:
        max_low = vEB_TREE_MAXIMUM(V.cluster[high(x, V.u)])
        if max_low != None and low(x, V.u) < max_low:
            offset = vEB_TREE_SUCCESSOR(V.cluster[high(x, V.u)], low(x,V.u))
            return index(high(x, V.u), offset, V.u)
        else:
            succ_cluster = vEB_TREE_SUCCESSOR(V.summary, high(x, V.u))
            if succ_cluster == None:
                return None
            else:
                offset = vEB_TREE_MINIMUM(V.cluster[succ_cluster])
                return index(succ_cluster, offset, V.u)

def vEB_TREE_PREDECESSOR(V, x):
    if V.u == 2:
        if x == 1 and V.min == 0:
            return 0
        else:
            return None
    elif V.max != None and x > V.max:
        return V.max
    else:
        min_low = vEB_TREE_MINIMUM(V.cluster[high(x, V.u)])
        if min_low != None and low(x, V.u) > min_low:
            offset = vEB_TREE_PREDECESSOR(V.cluster[high(x, V.u)], low(x, V.u))
            return index(high(x, V.u), offset, V.u)
        else:
            pred_cluster = vEB_TREE_PREDECESSOR(V.summary, high(x, V.u))
            if pred_cluster == None:
                if V.min != None and x > V.min:
                    return V.min
                else:
                    return None
            else:
                offset = vEB_TREE_MAXIMUM(V.cluster[pred_cluster])
                return index(pred_cluster, offset, V.u)

def vEB_EMPTY_TREE_INSERT(V, x):
    V.min = x
    V.max = x

def vEB_TREE_INSERT(V, x):
    if V.min == None:
        vEB_EMPTY_TREE_INSERT(V, x)
    else:
        if x < V.min:
            x, V.min = V.min, x
        if V.u > 2:
            if vEB_TREE_MINIMUM(V.cluster[high(x, V.u)]) == None:
                vEB_TREE_INSERT(V.summary, high(x, V.u))
                vEB_EMPTY_TREE_INSERT(V.cluster[high(x, V.u)], low(x, V.u))
            else:
                vEB_TREE_INSERT(V.cluster[high(x, V.u)], low(x, V.u))
        if x > V.max:
            V.max = x

def vEB_TREE_DELETE(V, x):
    if V.min == V.max:
        V.min = None
        V.max = None
    elif V.u == 2:
        if x == 0:
            V.min = 1
        else:
            V.min = 0
        V.max = V.min
    else:
        if x == V.min:
            first_cluster = vEB_TREE_MINIMUM(V.summary)
            x = index(first_cluster, vEB_TREE_MINIMUM(V.cluster[first_cluster]), V.u)
            V.min = x
        vEB_TREE_DELETE(V.cluster[high(x, V.u)], low(x, V.u))
        if vEB_TREE_MINIMUM(V.cluster[high(x, V.u)]) == None:
            vEB_TREE_DELETE(V.summary, high(x, V.u))
            if x == V.max:
                summary_max = vEB_TREE_MAXIMUM(V.summary)
                if summary_max == None:
                    V.max = V.min
                else:
                    V.max = index(summary_max, vEB_TREE_MAXIMUM(V.cluster[summary_max]), V.u)
        elif x == V.max:
            V.max = index(high(x, V.u), vEB_TREE_MAXIMUM(V.cluster[high(x, V.u)]), V.u)

if __name__ == "__main__":
    V = vEB_TREE_CREATE(16)

    print(vEB_TREE_MEMBER(V, 1))
    print(vEB_TREE_MEMBER(V, 2))
    print(vEB_TREE_MEMBER(V, 3))
    vEB_TREE_INSERT(V, 1)
    vEB_TREE_INSERT(V, 2)
    vEB_TREE_INSERT(V, 3)
    print(vEB_TREE_MEMBER(V, 1))
    print(vEB_TREE_MEMBER(V, 2))
    print(vEB_TREE_MEMBER(V, 3))
    
    print(vEB_TREE_MINIMUM(V))
    print(vEB_TREE_MAXIMUM(V))
    print(vEB_TREE_SUCCESSOR(V, 0))
    print(vEB_TREE_SUCCESSOR(V, 1))
    print(vEB_TREE_SUCCESSOR(V, 2))
    print(vEB_TREE_SUCCESSOR(V, 3))
    print(vEB_TREE_PREDECESSOR(V, 4))
    print(vEB_TREE_PREDECESSOR(V, 3))
    print(vEB_TREE_PREDECESSOR(V, 2))
    print(vEB_TREE_PREDECESSOR(V, 1))
    print("----------------------------")
    vEB_TREE_DELETE(V, 3)
    print(vEB_TREE_MINIMUM(V))
    print(vEB_TREE_MAXIMUM(V))
    print(vEB_TREE_SUCCESSOR(V, 0))
    print(vEB_TREE_SUCCESSOR(V, 1))
    print(vEB_TREE_SUCCESSOR(V, 2))
    print(vEB_TREE_SUCCESSOR(V, 3))
    print(vEB_TREE_PREDECESSOR(V, 4))
    print(vEB_TREE_PREDECESSOR(V, 3))
    print(vEB_TREE_PREDECESSOR(V, 2))
    print(vEB_TREE_PREDECESSOR(V, 1))
    
显而易见这些操作的时间复杂度为lglgn。

习题解答

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值