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;
}
posted @ 2017-10-19 21:40  给我一个理由  阅读(216)  评论(0编辑  收藏  举报