van Emda Boas维护了一个整数集合[0,Max)(无重复),其中Max必须等于2的正整数次幂。它支持以下操作:
(1)插入一个数字;
(2)删除一个数字;
(3)询问某一个数字在不在这个集合中;
(4)询问集合的最大最小值;
(5)询问一个数字的前驱或者后继。
每个操作的复杂度最大为O(loglog(n))

  1 #include <cmath>
  2 #include <algorithm>
  3
  4 /***
  5   维护的集合范围为[0,MAXU-1]
  6   MAXU必须为2的正整数次幂
  7   MAXU<=2^30
  8 ***/
  9
 10
 11 template<int MAXU>
 12 class VanEmdeBoasTree
 13 {
 14 private:
 15
 16     int m_inValidValue;
 17
 18     struct TreeNode
 19     {
 20         int Min,Max;
 21
 22         /**
 23           u为2的某次幂
 24           设u=2^k
 25           若k为偶数 UpBit=k/2
 26           若k为奇数 UpBit=(k+1)/2
 27           DownBit=k-UpBit
 28         **/
 29         int u;
 30         int UpBit;
 31         int DownBit;
 32
 33         TreeNode* summary;
 34         TreeNode** cluster;
 35
 36         /**
 37           x的高UpBit位
 38         **/
 39         int high(int x)
 40         {
 41             return x>>DownBit;
 42         }
 43
 44         /**
 45           x的低DownBit位
 46         **/
 47         int low(int x)
 48         {
 49             return x&((1<<DownBit)-1);
 50         }
 51
 52         int index(int hx,int lx)
 53         {
 54             return (hx<<DownBit)|lx;
 55         }
 56     };
 57     TreeNode* m_root;
 58     int m_MAXRANGE;
 59
 60
 61     /**
 62        已知u=2^k  返回k
 63     **/
 64     int GetSumBit(const int u)
 65     {
 66         return int(log2(u)+0.5);
 67     }
 68
 69     void build(TreeNode* &root,const int u)
 70     {
 71         root->Min=m_inValidValue;
 72         root->Max=m_inValidValue;
 73         root->u=u;
 74
 75         if(2==u) return;
 76
 77         const int k=GetSumBit(u);
 78         root->UpBit=(k+1)>>1;
 79         root->DownBit=k>>1;
 80
 81         root->summary=new TreeNode;
 82         build(root->summary,1<<root->UpBit);
 83
 84         root->cluster=new TreeNode*[1<<root->UpBit];
 85         for(int i=0;i<(1<<root->UpBit);i++)
 86         {
 87             root->cluster[i]=new TreeNode;
 88             build(root->cluster[i],1<<root->DownBit);
 89         }
 90     }
 91
 92     int GetMinValue(TreeNode *rt) { return rt->Min; }
 93     int GetMaxValue(TreeNode *rt) { return rt->Max; }
 94
 95     int getSuccessor(TreeNode* curNode,int x)
 96     {
 97         if(2==curNode->u)
 98         {
 99             if(x==0&&curNode->Max==1) return 1;
100             else return m_inValidValue;
101         }
102         else if(curNode->Min!=m_inValidValue&&x<curNode->Min)
103         {
104             return curNode->Min;
105         }
106         else
107         {
108             const int highX=curNode->high(x);
109             const int lowX=curNode->low(x);
110
111             int MaxLow=GetMaxValue(curNode->cluster[highX]);
112             if(MaxLow!=m_inValidValue&&lowX<MaxLow)
113             {
114                 return curNode->index(highX,
115                                       getSuccessor(curNode->cluster[highX],lowX));
116             }
117             else
118             {
119                 int successCluster=getSuccessor(curNode->summary,highX);
120                 if(successCluster==m_inValidValue) return m_inValidValue;
121                 else
122                 {
123                     return curNode->index(successCluster,
124                                           GetMinValue(curNode->cluster[successCluster]));
125                 }
126             }
127         }
128     }
129
130     int getPredecessor(TreeNode* curNode,int x)
131     {
132         if(2==curNode->u)
133         {
134             if(1==x&&0==curNode->Min) return 0;
135             else return m_inValidValue;
136         }
137         else if(curNode->Max!=m_inValidValue&&x>curNode->Max)
138         {
139             return curNode->Max;
140         }
141         else
142         {
143             const int highX=curNode->high(x);
144             const int lowX=curNode->low(x);
145
146             int MinLow=GetMinValue(curNode->cluster[highX]);
147             if(MinLow!=m_inValidValue&&lowX>MinLow)
148             {
149                 return curNode->index(highX,
150                                       getPredecessor(curNode->cluster[highX],lowX));
151             }
152             else
153             {
154                 int predCluster=getPredecessor(curNode->summary,highX);
155                 if(predCluster==m_inValidValue)
156                 {
157                     if(curNode->Min!=m_inValidValue&&x>curNode->Min)
158                     {
159                         return curNode->Min;
160                     }
161                     else return m_inValidValue;
162                 }
163                 else
164                 {
165                     return curNode->index(predCluster,
166                                           GetMaxValue(curNode->cluster[predCluster]));
167                 }
168             }
169         }
170     }
171
172     void insertEmptyNode(TreeNode* curNode,int x)
173     {
174         curNode->Min=curNode->Max=x;
175     }
176
177     void insert(TreeNode* curNode,int x)
178     {
179         if(curNode->Min==m_inValidValue)
180         {
181             insertEmptyNode(curNode,x);
182             return;
183         }
184         if(x==curNode->Min||x==curNode->Max) return;
185         if(x<curNode->Min)
186         {
187             std::swap(x,curNode->Min);
188         }
189         if(curNode->u>2)
190         {
191             const int highX=curNode->high(x);
192             const int lowX=curNode->low(x);
193             if(GetMinValue(curNode->cluster[highX])==m_inValidValue)
194             {
195                 insert(curNode->summary,highX);
196                 insertEmptyNode(curNode->cluster[highX],lowX);
197             }
198             else
199             {
200                 insert(curNode->cluster[highX],lowX);
201             }
202         }
203         if(x>curNode->Max) curNode->Max=x;
204     }
205
206     void remove(TreeNode* curNode,int x)
207     {
208         if(curNode->Min==curNode->Max)
209         {
210             curNode->Min=curNode->Max=m_inValidValue;
211             return;
212         }
213         if(curNode->u==2)
214         {
215             if(x==0) curNode->Min=1;
216             else curNode->Min=0;
217             curNode->Max=curNode->Min;
218             return;
219         }
220         if(x==curNode->Min)
221         {
222             int firstCluster=GetMinValue(curNode->summary);
223             x=curNode->index(firstCluster,
224                              GetMinValue(curNode->cluster[firstCluster]));
225             curNode->Min=x;
226         }
227
228         const int highX=curNode->high(x);
229         const int lowX=curNode->low(x);
230         remove(curNode->cluster[highX],lowX);
231         if(GetMinValue(curNode->cluster[highX])==m_inValidValue)
232         {
233             remove(curNode->summary,highX);
234             if(x==curNode->Max)
235             {
236                 int summaryMax=GetMaxValue(curNode->summary);
237                 if(summaryMax==m_inValidValue) curNode->Max=curNode->Min;
238                 else
239                 {
240                     curNode->Max=curNode->index(summaryMax,
241                                                 GetMaxValue(curNode->cluster[summaryMax]));
242                 }
243             }
244         }
245         else
246         {
247             if(x==curNode->Max)
248             {
249                 curNode->Max=curNode->index(highX,
250                                             GetMaxValue(curNode->cluster[highX]));
251             }
252         }
253     }
254
255 public:
256
257     /**
258       构造函数需要提供类型的无效值
259     **/
260     VanEmdeBoasTree(const int inValidValue=-1)
261     {
262         m_MAXRANGE=MAXU;
263         m_inValidValue=inValidValue;
264         m_root=new TreeNode;
265         build(m_root,MAXU);
266     }
267
268     /**
269       key存在 返回1 否则返回0
270     **/
271     int isExist(int key)
272     {
273         if(key<0||key>=MAXU) return 0;
274
275         TreeNode* curNode=m_root;
276         while(1)
277         {
278             if(key==curNode->Min||key==curNode->Max) return 1;
279             else if(2==curNode->u) return 0;
280             else
281             {
282                 TreeNode *nextNode=curNode->cluster[curNode->high(key)];
283                 key=curNode->low(key);
284                 curNode=nextNode;
285             }
286         }
287     }
288
289     /**
290       查找key的后继 即大于key最小的值
291       若没有 返回m_inValidValue
292     **/
293     int getSuccessor(int key)
294     {
295         if(key<0) return GetMinValue(m_root);
296         if(key>=m_MAXRANGE) return m_inValidValue;
297         return getSuccessor(m_root,key);
298     }
299
300     /**
301       查找key的前驱 即小于key最大的值
302       若没有 返回m_inValidValue
303     **/
304     int getPredecessor(int key)
305     {
306         if(key<0) return m_inValidValue;
307         if(key>=m_MAXRANGE) return GetMaxValue(m_root);
308         return getPredecessor(m_root,key);
309     }
310
311     void insert(int key)
312     {
313         if(key<0||key>=m_MAXRANGE) return;
314         insert(m_root,key);
315     }
316
317     void remove(int key)
318     {
319         if(key<0||key>=m_MAXRANGE) return;
320         remove(m_root,key);
321     }
322
323     int GetMaxValue()
324     {
325         return GetMaxValue(m_root);
326     }
327
328     int GetMinValue()
329     {
330         return GetMinValue(m_root);
331     }
332 };

van Emda Boas相关推荐

  1. BZOJ 3685: 普通van Emde Boas树( 线段树 )

    建颗权值线段树就行了...连离散化都不用... 没加读入优化就TLE, 加了就A掉了...而且还快了接近1/4.... ---------------------------------------- ...

  2. 算法导论读书笔记(20)van Emde Boas树

    第五部分 高级数据结构 第20章 van Emde Boas树 van Emde Boas树支持优先队列操作以及一些其他操作,每个操作最坏情况运行时间为O(lglgn).而这种数据结构限制关键字必须为 ...

  3. van Emde Boas 树 数据结构说解

    van Emde Boas 树的定义 直观上看,vEB 树保存了一个有序的集合,并支持以 O(lglgn) 的时间复杂度在 vEB 树上进行最小最大值查询.单值存在性查询.单值前驱后继查询.单值插入维 ...

  4. 算法导论-van Emde Boas树

    van Emde Boas树 van Emde Boas树中文名不知道,所以暂且叫它v树吧.v树是一种数据结构,和二叉树.红黑树类似.一种数据结构被创建出来,肯定有其特别的优点,v树的优点就是实现数据 ...

  5. 详解Van emde boas tree

    详解Van Emde Boas Tree 在这篇文章中, 我将带大家走进Van Emde Boas tree这种数据结构 Motivation 在读这篇文章之前, 相信大家都已经很了解二叉搜索树了, ...

  6. 《算法导论3rd第二十章》van Emde Boas树

    前言 前面介绍的二叉堆,红黑树以及斐波那契堆,其重要的操作都要O(lgn).当特定条件下,能否够规避Ω(lglgn)下界的限制?在本章中,我们将看到:van Emde Boas树支持优先队列操作及一些 ...

  7. van Emde Boas tree

    介绍 van Emde Boas tree是一种适用于0-u数据存储的一种数据类型.它每次根据u的一半来依次递减,直到最后减少到2为止.对数据有一定要求:要求u是2的2k或者2k+1次方. 单个结点的 ...

  8. 【算法学习笔记】van Emde Boas树

    参考算法导论第20章 van Emde Boas树 文章目录 1. 基本方法 1.1 直接寻址 1.2 叠加的二叉树结构 `Superimposing a binary tree structure` ...

  9. 6.6 van Emde Boas树

      我将按四个步骤来逐一引入到van Emde Boas树.从位图到索引位图,再到van Emde Boas原型,最后到van Emde Boas树. 位图与索引位图   在java中有这个一个类,叫 ...

最新文章

  1. 【互联网本周大事记】Uber估值400亿了呢!
  2. mysql 无论输入什么都是现实 not found_Java高频面试题及答案
  3. 在Gradle里访问任务(task)的几种方式
  4. ubuntu安装扩展在phpinfo显示不出来的解决办法
  5. 数据库服务器网页,服务器 数据库 网页前端
  6. 云片短信php接口_php与阿里云短信接口接入
  7. js 数字,金额 用逗号 隔开。数字格式化
  8. Xslt取节点集的指定位置记录的三种方法
  9. linux mysql端口启动失败怎么办,Linux下apache mysql等服务修改默认端口后无法正常启动解决办法...
  10. GIT学习笔记——1.2 起步 - Git 简史
  11. docker学习笔记3:镜像操作(查找和下载)
  12. 数字信号处理课程设计---带通滤波器的设计及其matlab实,数字信号处理课程设计---带通滤波器的设计及其MATLAB实现...
  13. Chrome浏览器安装IE_Tab
  14. Vue3.0官方文档
  15. 知途云仓2.0 淘宝礼品一件代发php源码
  16. Cocoa Touch基础
  17. 使用 *号在分别在控制台输出一个平行四边形、等腰三角形、菱形
  18. Golang验证身份证号码是否有效
  19. 数据分析 | 岭回归与LASSO回归
  20. 机器学习之偏斜类误差度量

热门文章

  1. react-native 组件之间传值
  2. 如何在 Linux 上录制你的终端操作
  3. Android -- 消息处理机制源码分析(Looper,Handler,Message)
  4. 创建OPPM的12个步骤
  5. IE再次曝出安全漏洞 微软表示正在调查
  6. 开源项目-基于Intel VT技术的Linux内核调试器
  7. 2018年机器视觉前景预测
  8. 编译与部署dubbo管控平台dubbo-admin
  9. busybox filesystem httpd php-5.5.31 sqlite3 webserver
  10. asp.net mvc @RenderBody()的问题