Example #1
0
        //移除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);
        }
Example #2
0
        /// <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);
        }