嗯今天写一个软件的时候不知不觉用到了BST,嗯,BST么,虽然实现很麻烦但是好在.NET已经实现了,直接调用呗……
[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;
}
}
可等我调用的时候才发现…… 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
{
}
http://blog.sina.com.cn/s/blog_8a2a44ff0101hwbf.html
http://blog.sina.com.cn/s/blog_8a2a44ff0101hwbf.html