📌  相关文章
📜  Van Emde Boas树|设置1 |基础与建设

📅  最后修改于: 2021-04-17 08:51:34             🧑  作者: Mango

强烈建议您充分了解Proto Van Emde Boas树。

Van Emde Boas Tree支持O(lglgN)时间的搜索,后继,前任,插入和删除操作,这比任何相关数据结构(例如优先级队列,二进制搜索树等)都要快。Van Emde Boas Tree可与O(1)一起使用最小和最大查询的时间复杂度。在此,N是定义树的Universe的大小,而lg是对数基数2。

注意: Van Emde Boas数据结构的密钥集必须在0到n的范围内定义(n是2 k的正整数),并且在不允许重复的密钥时可以使用。

缩略语:

  1. VEB是Van Emde Boas树的缩写。
  2. VEB( \sqrt{u} )是VEB的缩写,包含u个键。

Van Emde Boas树的结构:

范·埃姆德·博阿斯树

Van Emde Boas树是一个递归定义的结构。

  1. u :VEB树中存在的密钥数。
  2. 最小:包含在VEB树中的最小密钥。
  3. 最大值:包含VEB树中存在的最大密钥。
  4. 摘要:指向新VEB( \sqrt{u} )树,其中包含clusters数组中存在的键的概述。
  5. 簇:大小数组\sqrt{u}数组中的每个位置都指向新的VEB( \sqrt{u} ) 树。

参见下图以了解Van Emde Boas Tree的基础知识,尽管它并不代表Van Emde Boas Tree的实际结构:

VEB基础

对Van Emde Boas树的基本了解:

  1. Van Emde Boas树是递归定义的结构,类似于Proto Van Emde Boas树。
  2. 在Van Emde Boas树中,由于Van Emde Boas树存储树结构中存在的Minimum和Maximum键,因此最小和最大查询将在O(1)时间内工作。
  3. 添加“最大”和“最小”属性的优点,这有助于降低时间复杂度:
    • 如果VEB树的最小值和最大值中的任何一个为空(代码中为NIL或-1),则树中不存在任何元素。
    • 如果最小值和最大值相等,则结构中仅存在一个值。
    • 如果两者都存在且不同,则树中将存在两个或多个元素。
    • 我们可以通过在恒定时间(O(1))中根据条件设置最大值和最小值来插入和删除密钥,这有助于减少递归调用链:如果VEB中仅存在一个密钥,则只需设置该密钥即可删除该密钥最小和最大为nil值。同样,如果不存在键,则只需将min和max设置为要插入的键即可插入。这些是O(1)操作。
    • 在后续查询和先前查询中,我们可以根据VEB的最小值和最大值进行决策,这将使我们的工作更加轻松。

在Pro Van Vande Boas树中,宇宙大小的大小被限制为2 2 k类型,但是在Van Emde Boas树中,它允许宇宙大小精确地为2的幂。因此,我们需要修改Proto Van Emde Boas树中使用的High(x),low(x),generate_index()帮助器函数,如下所示。

  1. 高(x):它将返回下限(x / ceil( \sqrt{u} )),基本上是其中存在键x的聚簇索引。

    高(x)=底线(x / ceil( \sqrt{u} ))

  2. 低(x):它将返回x mod ceil( \sqrt{u} ),即其在集群中的位置。

    低(x)= x%ceil( \sqrt{u} )

  3. generate_index(a,b):它将从键在簇b中的位置及其簇索引a返回键的位置。

    generate_index(a,b)= a * ceil( \sqrt{u} )+ b

    Van Emde Boas树的构造:Van Emde Boas树的构造与Proto Van Emde Boas树的构造非常相似。此处的区别在于,我们允许Universe的大小为2的任意幂,因此high(),low(),generate_index()会有所不同。

    要构造空的VEB:步骤与Proto VEB相同,只是在每个VEB中添加了最小和最大两项。为了表示最小值和最大值为零,我们将其表示为-1。

    注意:在基本情况下,我们只需要最小值和最大值,因为在添加最小值和最大值之后,添加大小为2的簇将是多余的。

    范Emde蟒蛇树大小4

    下面是实现:

    // C++ implementation of the approach
    #include 
    using namespace std;
      
    class Van_Emde_Boas {
      
    public:
        int universe_size;
        int minimum;
        int maximum;
        Van_Emde_Boas* summary;
        vector clusters;
      
        // Function to return cluster numbers
        // in which key is present
        int high(int x)
        {
            int div = ceil(sqrt(universe_size));
            return x / div;
        }
      
        // Function to return position of x in cluster
        int low(int x)
        {
            int mod = ceil(sqrt(universe_size));
            return x % mod;
        }
      
        // Function to return the index from
        // cluster number and position
        int generate_index(int x, int y)
        {
            int ru = ceil(sqrt(universe_size));
            return x * ru + y;
        }
      
        // Constructor
        Van_Emde_Boas(int size)
        {
            universe_size = size;
            minimum = -1;
            maximum = -1;
      
            // Base case
            if (size <= 2) {
                summary = nullptr;
                clusters = vector(0, nullptr);
            }
            else {
                int no_clusters = ceil(sqrt(size));
      
                // Assigning VEB(sqrt(u)) to summary
                summary = new Van_Emde_Boas(no_clusters);
      
                // Creating array of VEB Tree pointers of size sqrt(u)
                clusters = vector(no_clusters, nullptr);
      
                // Assigning VEB(sqrt(u)) to all of its clusters
                for (int i = 0; i < no_clusters; i++) {
                    clusters[i] = new Van_Emde_Boas(ceil(sqrt(size)));
                }
            }
        }
    };
      
    // Driver code
    int main()
    {
        // New Van_Emde_Boas tree with u = 16
        Van_Emde_Boas* akp = new Van_Emde_Boas(4);
    }