详解Van emde boas tree

详解Van Emde Boas Tree

在这篇文章中, 我将带大家走进Van Emde Boas tree这种数据结构

Motivation

在读这篇文章之前, 相信大家都已经很了解二叉搜索树了, 如果对二叉搜索树不太了解的同学, 可以参考这篇文章。
https://www.geeksforgeeks.org/binary-search-tree-data-structure/
我们知道, 对于平衡二叉树而言, 查找, 插入, 删除的复杂度是 O ( log ⁡ ( n ) ) O(\log(n)) O(log(n))
平衡二叉树每一个节点存的值是可以任意大, 或者任意小的, 但是生活中我们的输入是有一定范围的, 在这样的情况下, 是否可以利用分治设计出一种数据结构, 来达到比二叉树更好的性能呢? 在这样的背景下诞生了Van Emde Boas Tree

在进入正文之前, 我们先来看生活中Van Emde Boas Tree的两个例子。

  1. 假设在存储IP地址的时候, 需要快速查找某个IP地址(2 ^32大小)是否在访问的列表中, 或者需要找到比这个IP地址大一点或者小一点的IP作为重新分配的IP。
  2. 一条路上开了很多商店, 用int来表示商店的位置(假设位置为1-256之间的数), 不断插入, 删除商店, 同时需要找到离某个商店最近的商店在哪里。

在这两个例子中, Van Emde Boas Tree体现了它的应用价值。

结构详解

在这一小节中, 我将详解Van Emde Boas Tree的结构

Van Emde Boas Tree的功能接口

Van emde Boas Tree主要有以下一些功能

  • insert (插入一个新的数字)
  • delete (删除一个数字)
  • find (查看某个数字是否存在)
  • successor (查找在已有的数字中比某个数字大的第一个数字)
  • predecessor (查找在已有的数字中比某个数字小的第一个数字)

从哈希表说起

在讲van Emde Boas Tree之前, 不得不提哈希表
下图展示的是一个哈希表
如果存在x, 那么hash[x] = 1
如果不存在x, 那么hash[x] = 0
因此下面这个表可以用来记录0-15这16个数字在表中的存在情况
在这里插入图片描述
那么这个hash表完成Van emde Boas Tree的任务需要多少的复杂度呢
空间复杂度 O ( n ) O(n) O(n)
insert和delete的时间复杂度为 O ( 1 ) O(1) O(1)
但是问题来了, 求successor和predecessor的复杂度是多少呢
答案是 O ( n ) O(n) O(n)
比如:找1的后继(successor), 那么需要从2遍历到9, 才找到, 极端情况, 表中只有0和15, 那么需要遍历整个表才能找到一个数字的后继, 因此对于一个频繁查找前驱和后继的任务, 哈希表的复杂度还不够理想。

由Bit Vector建多叉树

不难想到, 如果对hash的结果再进行hash, 构建hash树, 会让查找变的容易, 因此由hash再hash的这种思想, 建立了hash表的改进版——多叉hash树。
在这里插入图片描述

Van Emde Boas Tree的结构

伪代码详解

C++实现

#include <vector>
#include <string>
#include <iostream>
#include <memory>
#include <unordered_map>
#include <algorithm>
#include <stack>
#include <queue>
#include <string.h>
#include <stdlib.h>
#include <list>
#include <stdio.h>
#include <set>
#include <math.h>
#include <complex>
#include <map>

using namespace std;
#define ERR_NOT_FOUND -1000000000

typedef unsigned long long llu;
typedef unsigned long long DataType;

class VebTree {
   
protected:
    llu size; // size of van emde boas tree
    llu subSize;
    DataType *minValue, *maxValue; // store min and max value
    VebTree *summary;
    VebTree **cluster;
    
    llu high(DataType x) {
   
        return x / subSize;
    }
    
    llu low(DataType x) {
   
        return x % subSize;
    }
    
public:
    VebTree(llu u) : size(u), minValue(NULL), maxValue(NULL) {
   
        if (u == 2) {
   
            this->summary = NULL;
            this->cluster = NULL;
        }
        else {
   
            subSize = (llu) 
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值