5.2.ISet SortedSet
Node
// 这个Node就比二叉树节点多了一个IsRed属性而已啊,有什么不同呢
bool IsRed;
T Item;
Node Left;
Node Right;
ctor
1. public Node(T item){
//默认创建红色节点,我们不需要手动创建黑色节点
this.Item=item;
IsRed=true;
}
2. public Node(T item,bool isRed){
this.Item = item;
this.IsRed = isRed;
}
SortedSet system.dll 2447行,可以说非常复杂
Node root;
IComparer<T> comparer;
int count;
int version;
const int StackAllocThreshold = 100;
接口继承
ISet<T>
ICollection<T>
ICollection,ISerializable...
ctor
1. public SortedSet(){this.comparer=Comparer.Default;}
2. public SortedSet(IComparer<T> comparer){this.comparer=comparer;}
在不提供collection的时候,他是不会初始化root节点的,所以直接看Add方法
public bool Add(T item)
return AddIfNotPresent(item);
internal virtual bool AddIfNotPresent(T item)
internal virtual bool AddIfNotPresent(T item){
if(root == null){//empty tree
root =new Node(item,false);
count =1;
version++;
return true;
//添加第一个节点就是root
}
// search for a node at bottom to insert the newe node;
// if we can guanratee the node we found is not a 4-node
Node current = root;
Node parent = null;
Node grandParent = null;
Node greatGrandParent = null;
version++; //虽然没有新增节点,但是还是会修改树结构(通过旋转)
int order = 0;
while(current != null){
//如果相同的话,因为他是set,所以不管
order = comparer.Compare(item,current.Item);
if(order == 0){
root.IsRed = false;
return false;
}
// split a 4-node into two 2-nodes
if (Is4Node(current)) {
Split4Node(current);
// We could have introduced two consecutive red nodes after split. Fix that by rotation.
if (IsRed(parent)) {
InsertionBalance(current, ref parent, grandParent, greatGrandParent);
}
}
greatGrandParent = grandParent;
grandParent = parent;
parent = current;
current = (order < 0) ? current.Left : current.Right;
//这上面整个操作是为了计算出parent吗
}
Node node = new Node(item);
if(order>0){
parent.Right = node;
}else{
parent.Left = node;
}
// the new node will be red, so we will need to adjust the colors if parent node is also red
if (parent.IsRed) {
InsertionBalance(node, ref parent, grandParent, greatGrandParent);
}
// Root node is always black
root.IsRed = false;
++count;
return true;
}
private void InsertionBalance()
ctor
1. public SortedSet(){this.comparer=Comparer.Default;}
2. public SortedSet(IComparer<T> comparer){this.comparer=comparer;}
3. public SortedSet(IEnumerable<T> collection,IComparer<T> comparer){
//重点
1. 判断如果是普通的collection的话
List<T> els = new List<T>(collection);
els.Sort(this.comparer);
2. 移除数组中重复的数据
for(int i=1;i<els.Count;i++){
if(comparer.Compare(els[i],els[i-1]==0)){
els.RemoveAt(i);
i--;
}
}
3. root = ConstructRootFromSortedArray(els.ToArray(),0,els.Count-1,null);
4. count = els.Count;
5. version++
}
private void ConstructRootFromSotredArray(T[] array,int startIndex,int endIndex,Node redNode)
size=endIndex-startIndex+1; //默认是数组的count
Node root = null
if(size == 1){
root = new Node(arr[startIndex],false);
if(redNode!=null){
root.Left=redNode;
}
}else if(size == 2){
root = new Node(arr[startIndex],false);
root.Right = new Node(arr[endIndex],false);
root.Right.IsRed = true;
if(redNode!=null){
root.Left=redNode;
}
}else if(size==3){
root = new Node(arr[startIndex + 1],false);
root.Left = new Node(arr[startIndex],false);
root.Right = new Node(arr[endIndex],false);
if(redNode!=null){
root.Left.Left = redNode;
}
}else {
int midpt=((startIndex+endIndex)/2);
root = new Node(arr[midpt],false);
root.Left = ConstructRootFromSortedArray(arr,startIndex,midpt-1,redNode);
if(size%2==0){
root.Right = ConstructRootFromSortedArray(arr, midpt + 2, endIndex, new Node(arr[midpt + 1], true));
} else {
root.Right = ConstructRootFromSortedArray(arr, midpt + 1, endIndex, null);
}
return root;
}
这就是