C# 平衡二叉树 SBT 源码

嗯今天写一个软件的时候不知不觉用到了BST,嗯,BST么,虽然实现很麻烦但是好在.NET已经实现了,直接调用呗……
可等我调用的时候才发现…… MS根本没有给你开放接口……用反编译一看,其实.NET早就把红黑树实现了,就是SortedSet只是因为MS懒得给你写帮助文档(这不是我说的,是Jeffrey在CLRVIA C#里说的……)于是么…… 你就只能默默地用反编译去提取了……
只是…… 反正我是没有提取出来……引用的其他internal类太多了,懒得一个个提取了,干脆直接写了个SBT人在这里供大家使用……
因为是SBT么,刚刚出来的东西,所以就先实现了陈启峰在他论文里提到的功能,再加了一些我自己的,也就是:
Add 添加
Remove 删除
Rank获取第一个(最后一个)值与参数相同的节点的排名
Select 返回排名是i的那个值
Pred 返回比一个值小的最大的值
Succ 返回比一个值大的最小的值
而且都是 ln 复杂度(这不废话么……)

然后么,就是源码了,这个是可以直接使用的,注释已经写好(虽然只是对每个函数的描述)
反正我是大致测了一下,应该没有错的……
然后性能么…… 

运算量:3x10^5
我的实现版本MS家的红黄黑树
Add:12.61 8.34
Remove:6.53 6.86
单位:秒
现在就测了这两个,我之后可能会把其他补上。
然后记得在编译时,在项目属性的生成页下头把代码优化加上,不然会慢6倍吧(我车的时候是这样……)……

把System.dll和  System.Runtime.Serialization.dll  引用上就够了……

using System;
usingSystem.Runtime.Serialization;
usingSystem.Security.Permissions;

namespaceSystem.Collections.Generic
{
    [Serializable]
    public class SBTree<T> :IEnumerable<T>,ISerializable
    {
        [Serializable]
        sealed class Node :IEquatable<Node>,ISerializable
        {
            public Node(T data) { Data = data; Size = 1;}
            public Node() { }
            Node(SerializationInfo info, StreamingContextcontext)
            {
                Data =(T)info.GetValue("Data", typeof(T));
                Left =(Node)info.GetValue("Left", typeof(Node));
                Right =(Node)info.GetValue("Right", typeof(Node));
                Father =(Node)info.GetValue("Father", typeof(Node));
                Size =info.GetInt32("Size");
            }
            public void GetObjectData(SerializationInfoinfo, StreamingContext context)
            {
                info.AddValue("Data", Data);
                info.AddValue("Left", Left);
                info.AddValue("Right", Right);
                info.AddValue("Father", Father);
                info.AddValue("Size", Size);
            }

            public T Data { get; internal set;}
            public int Size { get; internal set;}
            internal Node left, right;
            public Node Left { get { return left; } internalset { left = value; } }
            public Node Right { get { return right; }internal set { right = value; } }
            public Node Father { get; internal set;}

            public static void RightRotate(ref Nodenode)
            {
                Node T =node.Left;
                if((node.Left = T.Right)!=null) T.Right.Father = node;
                node.Size+= (T.Right == null ? 0 : T.Right.Size) - T.Size;
                T.Right =node; T.Father = node.Father; node.Father = T;
                T.Size =T.Right.Size + (T.Left == null ? 0 : T.Left.Size) + 1;
                node =T;
            }
            public static void LeftRotate(ref Nodenode)
            {
                Node T =node.Right;
                if((node.Right = T.Left)!=null) T.Left.Father = node;
                node.Size+= (T.Left == null ? 0 : T.Left.Size) - T.Size;
                T.Left =node; T.Father = node.Father; node.Father = T;
                T.Size =T.Left.Size + (T.Right == null ? 0 : T.Right.Size) +1;
                node =T;
            }
            public static void Maintain(ref Node node, boolmaintain_right)
            {
                if (node== null) return;
                if(maintain_right)
                {
                    if (node.Right == null)return;
                    int lsize;
                    if (node.Left == null) lsize= 0; else lsize = node.Left.Size;
                    if (node.Right.Right != null&& node.Right.Right.Size> lsize)
                        Node.LeftRotate(ref node);
                    else if (node.Right.Left !=null && node.Right.Left.Size> lsize)
                    {
                        RightRotate(ref node.right);
                        LeftRotate(ref node);
                    }
                    else return;
                }
                else
                {
                    if (node.Left == null)return;
                    int rsize;
                    if (node.Right == null) rsize= 0; else rsize = node.Right.Size;
                    if (node.Left.Left != null&& node.Left.Left.Size> rsize)
                        Node.RightRotate(ref node);
                    else if (node.Left.Right !=null && node.Left.Right.Size> rsize)
                    {
                        Node.LeftRotate(ref node.left);
                        Node.RightRotate(ref node);
                    }
                    else return;
                }

                Maintain(ref node.left, false);
                Maintain(ref node.right, true);
                Maintain(ref node, false);
                Maintain(ref node, true);
            }

            public bool Equals(Node a)
            {
                returnData.Equals(a.Data);
            }
            public bool Equals(T a)
            {
                returnData.Equals(a);
            }
            public override bool Equals(objecta)
            {
                if (a isT)
                    returnEquals((T)a);
                else if (ais Node)
                    returnEquals((Node)a);
                returnfalse;
            }
            public override int GetHashCode()
            {
                returnData.GetHashCode();
            }
            public override string ToString()
            {
                returnData.ToString();
            }
        }

        public SBTree() { comparer =Comparer<T>.Default; }
        publicSBTree(IComparer<T> comparer) {this.comparer = comparer; }
        protectedSBTree(SerializationInfo info, StreamingContextcontext)
        {
            root =LoadNodeFromArray((T[])info.GetValue("data",typeof(T[])));
            comparer =(IComparer<T>)info.GetValue("comparer",typeof(IComparer<T>));
        }

        [SecurityPermission(SecurityAction.LinkDemand, Flags =SecurityPermissionFlag.SerializationFormatter)]
        public virtual voidGetObjectData(
        SerializationInfo info,StreamingContext context)
        {
            info.AddValue("data", ToArray());
            info.AddValue("comparer",comparer);
        }

        Node root;
        IComparer<T> comparer;


        void Add(ref Node node, Tv)
        {
            node.Size += 1;
            if (comparer.Compare(v, node.Data)<= 0)
            {
                if(node.left == null)
                {node.left = new Node(v); node.left.Father = node; }
                elseAdd(ref node.left, v);
                Node.Maintain(ref node, false);
            }
            else
            {
                if(node.right == null)
                {node.right = new Node(v); node.right.Father = node; }
                elseAdd(ref node.right, v);
                Node.Maintain(ref node, true);
            }
        }
        ///<summary>
        /// 在SBT中插入一个新的数据复杂度O(ln(count))
        ///</summary>
        /// <paramname="v"></param>
        public void Add(Tv)
        {
            if (root == null)
                root = newNode(v);
            else
                Add(refroot, v);
        }

        T Remove(ref Node node, Tv)
        {
            node.Size -= 1;
            int com_result = comparer.Compare(v,node.Data);
            if (com_result == 0 || (com_result< 0 && node.Left ==null) || (com_result > 0&& node.Right ==null))
            {
                T re =node.Data;
                if(node.Left == null)
                    node =node.Right;
                else if(node.Right == null)
                    node =node.Left;
                else
                    node.Data = Remove(refnode.left, node.Right.Data);
                returnre;
            }
            else if (com_result <0)
                returnRemove(ref node.left, v);
            else
                returnRemove(ref node.right, v);
        }
        ///<summary>复杂度O(ln(count))</summary>
        /// <paramname="v"></param>
        ///<returns>是否成功</returns>
        public bool Remove(Tv)
        {
            if (!Contains(v)) return false;
            Remove(ref root, v);
            return true;
        }

        ///<summary>
        /// 寻找到的是深度最浅的节点
        ///</summary>
        /// <paramname="node"></param>
        /// <paramname="v"></param>
        ///<returns></returns>
        Node Find(Node node, Tv)
        {
            if (node == null) return null;
            int com_res = comparer.Compare(v,node.Data);
            if (com_res == 0)
                returnnode;
            if (com_res < 0)
                returnFind(node.Left, v);
            else
                returnFind(node.Right, v);
        }
        Node Find(T v) { returnFind(root, v); }
        ///<summary>
        /// 此SBT中是否包含值为v的对象复杂度O(ln(count))
        ///</summary>
        /// <paramname="v"></param>
        ///<returns></returns>
        public bool Contains(T v) {return Find(v) != null; }
        bool Contains(Nodenode)
        {
            while (node.Father != null) node =node.Father;
            return Object.ReferenceEquals(root,node);
        }
        Node FindFirst(Node node, Tv)
        {
            if (node == null) return null;
            int com_res = comparer.Compare(v,node.Data);
            if (com_res == 0)
            {
                Node re =node;
                while(re.Left != null &&comparer.Compare(re.Left.Data, v) == 0) re = re.Left;
                returnre;
            }
            if (com_res < 0)
                returnFind(node.Left, v);
            else
                returnFind(node.Right, v);
        }
        Node FindFirst(T v) { returnFindFirst(root, v); }
        public T FindFirstData(Tv)
        {
            var node = FindFirst(root, v);
            if (node == null) returndefault(T);
            return node.Data;
        }
        Node FindLast(Node node, Tv)
        {
            if (node == null) return null;
            int com_res = comparer.Compare(v,node.Data);
            if (com_res == 0)
            {
                Node re =node;
                while(re.Right != null &&comparer.Compare(re.Right.Data, v) == 0) re =re.Right;
                returnre;
            }
            if (com_res < 0)
                returnFind(node.Left, v);
            else
                returnFind(node.Right, v);
        }
        Node FindLast(T v) { returnFindLast(root, v); }
        public T FindLastData(Tv)
        {
            var node = FindLast(root, v);
            if (node == null) returndefault(T);
            return node.Data;
        }
        ///<summary>
        ///查找SBT中与v相同的数据的数量
        ///</summary>
        /// <paramname="v"></param>
        ///<returns></returns>
        public int NumberContains(Tv)
        {
            int t = RankFirst(v);
            if (t == -1) return 0;
            return RankLast(v) - t + 1;
        }


        ///<summary>
        /// 是否为空 复杂度O(1)
        ///</summary>
        public bool Empty { get {return root == null; } }
        ///<summary>
        /// 数据数量 复杂度O(1)
        ///</summary>
        public int Count
        {
            get
            {
                if (Empty)return 0;
                returnroot.Size;
            }
        }

        int Rank(Nodenode)
        {
            if (node == null) return -1;
            int re;
            if (node.Left == null) re = 1;
            else re = node.Left.Size + 1;
            while (node.Father != null)
            {
                if(Object.ReferenceEquals(node.Father.Right, node))
                    re += node.Father.Size -node.Size;
                node =node.Father;
            }
            return re;
        }
        ///<summary>
        /// 从小到大,查询第一个 v的排名(根据comparer进行排序) 复杂度O(ln(count))
        /// 排名从1开始
        ///</summary>
        /// <paramname="v"></param>
        ///<returns>排名</returns>
        public int RankFirst(Tv)
        {
            return Rank(FindFirst(v));
        }
        public int RankLast(Tv)
        {
            return Rank(FindLast(v));
        }

        Node Select(Node node, intrank)
        {
            if (node == null) return null;
            int com_res = rank - ((node.Left == null) ? 0 :node.Left.Size) - 1;
            if (com_res == 0) return node;
            else if (com_res < 0) returnSelect(node.Left, rank);
            else return Select(node.Right, rank -((node.Left == null) ? 0 : node.Left.Size) - 1);
        }
        ///<summary>
        /// 选中排名在rank处的数据,复杂度O(ln(count)),排名从1开始
        ///</summary>
        /// <paramname="rank"></param>
        ///<returns></returns>
        public T Select(intrank)
        {
            if (rank > Count || rank< 1) throw newArgumentException("rank小于1或者超过了Count", "rank");
            return Select(root, rank).Data;
        }

        ///<summary>
        /// O(1)
        ///</summary>
        /// <paramname="node"></param>
        ///<returns></returns>
        Node Pred(Nodenode)
        {
            if (node.Left != null)
            {
                Node re =node.Left;
                while(re.Right != null) re = re.Right;
                returnre;
            }
            else
            {
                Node re =node;
                while(re.Father != null &&!Object.ReferenceEquals(re.Father.Right, re)) re =re.Father;
                returnre.Father;
            }
        }
        ///<summary>
        /// O(1)
        ///</summary>
        /// <paramname="node"></param>
        ///<returns></returns>
        Node Succ(Nodenode)
        {
            if (node.Right != null)
            {
                Node re =node.Right;
                while(re.Left != null) re = re.Left;
                returnre; 
            }
            else
            {
                Node re =node;
                while(re.Father != null &&!Object.ReferenceEquals(re.Father.Left, re)) re =re.Father;
                returnre.Father;
            }
        }
        ///<summary>
        /// 寻找比v小的最大的数据
        ///</summary>
        /// <paramname="v"></param>
        ///<returns></returns>
        public T Pred(Tv)
        {
            var note = Pred(FindFirst(root,v));
            if (note == null) returndefault(T);
            return note.Data;
        }
        ///<summary>
        /// 寻找比v大的最小的数据
        ///</summary>
        /// <paramname="v"></param>
        ///<returns></returns>
        public T Succ(Tv)
        {
            var note = Succ(FindLast(root, v));
            if (note == null) returndefault(T);
            return note.Data;
        }

        Node FirstNode()
        {
            if (root == null) return null;
            Node re = root;
            while (re.Left != null) re =re.Left;
            return re;
        }
        Node LastNode()
        {
            if (root == null) return null;
            Node re = root;
            while (re.Right != null) re =re.Right;
            return re;
        }
        public T First()
        {
            return FirstNode().Data;
        }
        public T Last()
        {
            return LastNode().Data;
        }

        public struct SBT_Enumrator :IEnumerator,IEnumerator<T>
        {
            internalSBT_Enumrator(SBTree<T> from, boolforward)
            {
                current_SBT = from;
                this.forward = forward;
                current_Node = current_SBT.FirstNode();
            }
            bool forward;
            Node current_Node;
            SBTree<T>current_SBT;
            public T Current { get { returncurrent_Node.Data; } }
            object IEnumerator.Current { get { returnCurrent; } }
            public bool MoveNext()
            {
                if(current_Node == null) return false;
                if(!current_SBT.Contains(current_Node)) throw newInvalidOperationExceptio n("已经对SBT集合进行了修改,并且Current已经被删除");
                Nodere;
                if(forward)
                    re =current_SBT.Succ(current_Node);
                else
                    re =current_SBT.Pred(current_Node);
                if (re ==null) return false;
                current_Node = re;
                returntrue;
            }
            public void Reset()
            {
                current_Node = current_SBT.FirstNode();
            }
            public void Dispose()
            {
                current_SBT = null;
                current_Node = null;
            }
        }
        publicIEnumerator<T> GetEnumerator() {return new SBT_Enumrator(this, true); }
        IEnumeratorIEnumerable.GetEnumerator() { return new SBT_Enumrator(this, true);}
        public structSBT_R_EnumeraDev :IEnumerable<T>
        {
            internalSBT_R_EnumeraDev(SBTree<T> from) {current_SBT = from; }
            SBTree<T>current_SBT;
            publicIEnumerator<T> GetEnumerator() {return new SBT_Enumrator(current_SBT, false); }
            IEnumerator IEnumerable.GetEnumerator() { returnnew SBT_Enumrator(current_SBT, false); }
        }
        public IEnumerableAsReverse() { return new SBT_R_EnumeraDev(this); }

        public voidClear()
        {
            root = null;
        }
        public void CopyTo(T[] arr,int arrayIndex)
        {
            int i = 0;
            foreach (var a in this)
                arr[arrayIndex + i++] = a;
        }

        void writeToArray(T[] arr,ref int index, Node node)
        {
            if (node == null) return;
            writeToArray(arr, ref index,node.Left);
            arr[index++] = node.Data;
            writeToArray(arr, ref index,node.Right);
        }
        public T[]ToArray()
        {
            var re = new T[Count];
            int index = 0;
            writeToArray(re, ref index, root);
            return re;
        }
        ///<summary>
        /// 当sbt不为空时,复杂度:O(n*log(n))n为arr.Length
        /// 当sbt为空时,复杂度:O(n)n为arr.Length
        ///</summary>
        /// <paramname="arr"></param>
        public void AddRange(T[]arr)
        {
            if (root == null)
            { root = LoadNodeFromArray(arr); return;}
            foreach (var a in arr)
                Add(a);
        }
        static NodeLoadNodeFromArray(T[] arr, int index, int len)
        {
            if (len == 0) return null;
            Node re = new Node(arr[index + (len>> 1)]) { Size = len };
            if ((re.Left = LoadNodeFromArray(arr, index, len>> 1)) != null) re.Left.Father =re;
            if ((re.Right = LoadNodeFromArray(arr, index +(len >> 1) + 1, len - (len>> 1) - 1)) != null) re.Right.Father= re;
            return re;
        }
        static NodeLoadNodeFromArray(T[] arr)
        {
            return LoadNodeFromArray(arr, 0,arr.Length);
        }
        ///<summary>
        /// 复杂度O(arr.Length)
        ///</summary>
        /// <paramname="arr"></param>
        /// <paramname="compare"></param>
        ///<returns></returns>
        public staticSBTree<T> LoadFromArray(T[] arr,IComparer<T> compare =null)
        {
            if (compare == null) compare =Comparer<T>.Default;
            var re = newSBTree<T>(compare);
            re.root = LoadNodeFromArray(arr);
            return re;
        }
    }
}

http://blog.sina.com.cn/s/blog_8a2a44ff0101hwbf.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值