📌  相关文章
📜  Proto Van Emde蟒蛇树|套装5 |查询:最小,最大(1)

📅  最后修改于: 2023-12-03 15:18:42.757000             🧑  作者: Mango

Proto Van Emde蟒蛇树|套装5 |查询:最小,最大

简介

Proto Van Emde蟒蛇树(PVE tree)是一种用于实现无序集合的数据结构,支持插入、删除、查找、获取最小值和最大值操作,时间复杂度为O(log(log(u))),其中u为集合中元素的最大值。

PVE tree是Van Emde Boas在1977年提出来的,它的主要思想是将一棵大的树分解为多个小的子树,从而降低操作的时间复杂度。而Proto-Van Emde蟒蛇树是在PVE基础上进行了优化,可以将空间复杂度降至O(n),其中n为集合中元素的个数。

功能

Proto Van Emde蟒蛇树支持以下操作:

  • 插入值为x的元素
  • 删除值为x的元素
  • 查找值为x的元素,返回True or False
  • 获取最小值和最大值
实现

PVE tree实现比较复杂,涉及到很多小技巧,不过实现好之后,它的各个操作都非常快。这里我们给出PVE tree的Python实现。

class PVEtree:
    def __init__(self, u):
        self.u = u
        self.has_value = False
        self.min_value = None
        self.max_value = None
        if u == 2:
            self.children = [None, None]
        else:
            self.upper_sqrt = int(u**0.5 // 1)
            self.lower_sqrt = int((u**0.5 + 1) // 1)
            self.children = [PVEtree(self.upper_sqrt) for _ in range(self.lower_sqrt)]

    def insert(self, x):
        if self.u == 2:
            if x == 0:
                self.children[0] = PVEtree(0)
            else:
                self.children[1] = PVEtree(1)
            self.has_value = True
            self.min_value = x
            self.max_value = x
        else:
            hi = x // self.upper_sqrt
            lo = x % self.upper_sqrt
            if not self.children[hi].has_value:
                self.insert(hi)
            self.children[hi].insert(lo)
            if self.children[hi].min_value is None:
                self.children[hi].min_value = lo
                self.children[hi].max_value = lo
            else:
                self.children[hi].min_value = min(self.children[hi].min_value, lo)
                self.children[hi].max_value = max(self.children[hi].max_value, lo)
            self.has_value = True
            if self.min_value is None:
                self.min_value = x
                self.max_value = x
            else:
                self.min_value = min(self.min_value, x)
                self.max_value = max(self.max_value, x)

    def delete(self, x):
        if self.u == 2:
            if x == 0:
                if self.children[0].has_value:
                    self.children[0] = None
                    self.has_value = self.children[1].has_value
                    self.min_value = self.children[1].min_value
                    self.max_value = self.children[1].max_value
                else:
                    self.has_value = False
                    self.min_value = None
                    self.max_value = None
            else:
                if self.children[1].has_value:
                    self.children[1] = None
                    self.has_value = self.children[0].has_value
                    self.min_value = self.children[0].min_value
                    self.max_value = self.children[0].max_value
                else:
                    self.has_value = False
                    self.min_value = None
                    self.max_value = None
        else:
            hi = x // self.upper_sqrt
            lo = x % self.upper_sqrt
            self.children[hi].delete(lo)
            if not self.children[hi].has_value:
                self.children[hi] = None
            if self.min_value == x:
                if self.children[hi].has_value:
                    self.min_value = hi*self.upper_sqrt + self.children[hi].min_value
                else:
                    for i in range(hi-1, -1, -1):
                        if self.children[i] is not None:
                            self.min_value = i*self.upper_sqrt + self.children[i].min_value
                            break
                    else:
                        self.min_value = None
            if self.max_value == x:
                if self.children[hi].has_value:
                    self.max_value = hi*self.upper_sqrt + self.children[hi].max_value
                else:
                    for i in range(hi+1, self.lower_sqrt):
                        if self.children[i] is not None:
                            self.max_value = i*self.upper_sqrt + self.children[i].max_value
                            break
                    else:
                        self.max_value = None
            if not self.has_children():
                self.has_value = False
                self.min_value = None
                self.max_value = None

    def has_children(self):
        return any(self.children)

    def search(self, x):
        if self.u == 2:
            return self.has_value and (self.children[x] is not None)
        else:
            hi = x // self.upper_sqrt
            lo = x % self.upper_sqrt
            return self.children[hi].has_value and self.children[hi].search(lo)

    def find_min(self):
        return self.min_value

    def find_max(self):
        return self.max_value

这段代码中,我们定义了一个PVEtree类,表示一个PVE tree的实例。在初始化时,我们传入了树中所有元素能够取到的最大值u,根据它,我们可以计算出当前节点所表示的区间,以及它包含的子节点。

在PVEtree类中,我们实现了PVE tree的全部操作,其中insert()和delete()操作比较麻烦,都需要递归地向下访问PVE tree的子节点,而且还需要对min_value和max_value进行更新。search()、find_min()和find_max()操作比较简单,就不多赘述了。

结语

Proto Van Emde蟒蛇树是一种高效实用的数据结构,它可以解决一些复杂的集合问题。如果你对集合算法感兴趣,不妨学习一下PVE tree。