//移除val,移除前需判断是否包含 public vanEmdeBoasTreeDataInfo <TData> Remove(int key) { Contract.Requires <ArgumentOutOfRangeException>(key >= Min && key <= Max); var res = new vanEmdeBoasTreeDataInfo <TData>() { remove = true }; if (min == max)// there's only one value in cluster { res.HitNode = this; res.HitMin = true; res.rmdata = MinData; min = max = null; MinData = MaxData = default(TData); } else if (u == 1)// leaf node { res.HitMin = key == 0; res.HitNode = this; if (key == 0) { min = 1; res.rmdata = MinData; MinData = MaxData; } else { max = 0; res.rmdata = MaxData; MaxData = MinData; } } else { if (key == min)// key is the minimum { res.HitMin = true; res.HitNode = this; res.rmdata = MinData; int first = _summary.min.Value; key = first << lsqrt | _clusters[first].min.Value; // get the first node of first cluster min = key; // update min and key, then delete min from sub-cluster MinData = _clusters[first].MinData; _clusters[key >> lsqrt].Remove(key & lsbits); } else { res = _clusters[key >> lsqrt].Remove(key & lsbits); } int h = key >> lsqrt; if (_clusters[h].min == null) { _summary.Remove(h); // delete cluster from summary if (key == max) // if max is deleted, then find previous cluster to update maximum. { int?smax = _summary?.max; if (smax == null) { max = min; } else { max = smax << lsqrt | _clusters[smax.Value].max; MaxData = _clusters[smax.Value].MaxData; } } } else if (key == max) { max = h << lsqrt | _clusters[h].max; MaxData = _clusters[h].MaxData; } } num--; return(res); }
/// <summary> /// Insert a new node, if node with the key exists already, then update the data /// 插入新结点,若结点已存在则更新结点数据 /// </summary> /// <param name="key">插入结点的关键字</param> /// <param name="data">需要插入的数据</param> /// <param name="info">返回插入的位置信息</param> /// <param name="newNode">创建新结点的方法, 参数是结点全域大小, 用以生成自定义的结点</param> /// <returns>如果关键字不存在则返回<c>true</c>,关键字已存在则返回<c>false</c></returns> public bool Create(int key, TData data, out vanEmdeBoasTreeDataInfo <TData> info, Func <int, vanEmdeBoasTreeNode <TData> > newNode) { Contract.Requires <ArgumentOutOfRangeException>(key >= 0 && key <= UniverseSize); Contract.Requires <ArgumentNullException>(newNode != null); bool updated = true;// update log, if node is new, then num will be updated. info = new vanEmdeBoasTreeDataInfo <TData>() { HitNode = this, HitMin = true }; if (min == null)// the node is null { min = max = key; MinData = MaxData = data; num = 1; } else { bool replaced = false; if (key < min) // update min and insert min into sub-clusters { int temp = key; // swap data key = min.Value; min = temp; TData tempdata = data; data = MinData; MinData = tempdata; replaced = true; } else if (key == min) // update min { MinData = data; if (min == max) { MaxData = data; } return(false); } if (u > 1) { int h = key >> lsqrt, l = key & lsbits; if (_clusters[h] == null) { _clusters[h] = newNode(lsqrt); } if (_clusters[h].min == null) // sub-cluster is null { Summary.Create(h, null, createsummary); _clusters[h].min = _clusters[h].max = l; _clusters[h].MinData = _clusters[h].MaxData = data; _clusters[h].num = 1; if (!replaced) { info.HitNode = _clusters[h]; } } else { if (!replaced) { updated = _clusters[h].Create(l, data, out info, newNode); } else { _clusters[h].Create(l, data, newNode); } } } if (key > max) { max = key; MaxData = data; } else if (key == max) // update max { MaxData = data; if (!replaced) { return(false); } } if (updated) { num++; } } return(updated); }