实时排序算法(跳表)

说明:采用和Redis排序算法类似的跳表,支持大量数据的实时排序。

public class SkipListLevelInfo where T : class
{
    public SkipListNode Next;
    public uint Span;
}

public class SkipListNode where T : class
{
    public T Item { get; private set; }
    //level为0那一层的前面节点
    public SkipListNode Prev;
    //根据Level记录每一层的下一个节点以及中间间隔的距离
    public SkipListLevelInfo[] LevelsInfo { get; private set; }
    public SkipListNode(T obj, uint level)
    {
        this.Item = obj;
        this.LevelsInfo = new SkipListLevelInfo[level];
        for(int i=0;i();
        }
    }

}
/// 
/// 跳表,仿照redis的实现
/// 从小到大排,返回1,表示要交换,-1,表示不要交换,0表示是同一个元素
/// 注意不同元素不能返回0
/// Debug模式下,1000000次add 花费6.5s
/// 简单的原理图如下
/// level 3 ||    8------------------------------>1   0 
/// level 2 ||    2------>2------>4-------------->1   0
/// level 1 ||    2------>2------>2------>2------>1   0
/// level 0 ||    1-->1-->1-->1-->1-->1-->1-->1-->1   0
/// value         X   1   3   4   6   8   10  15  18  20
/// node          H   N1  N2  N3  N4  N5  N6  N7  N8  N9
/// 
/// 
public class SkipList where T : class
{
    private Random random;
    private SkipListNode header;
    private SkipListNode tail;
    private uint currentLevel;
    private uint maxLevel;
    private Comparison comparison;
    public uint Count { get; private set; }
    /// 

    /// 

    public SkipList(Comparison comparison, uint maxLevel = 32)
    {
        this.comparison = comparison;
        random = new Random((int)(DateTime.Now - TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1))).TotalSeconds);
        this.maxLevel = maxLevel;
        currentLevel = 1;
        Count = 0;
        header = new SkipListNode(null,maxLevel);
        for (int i = 0; i < maxLevel; i++)
        {
            header.LevelsInfo[i].Next = null;
            header.LevelsInfo[i].Span = 0;
        }
        this.header.Prev = null;
        this.tail = null;
    }




    public void Add(T item)
    {
        //这个内存分配有点耗时间,可以优化
        SkipListNode[] needUpdate = new SkipListNode[this.maxLevel];
        uint[] rank = new uint[this.maxLevel];


        SkipListNode currentNode = header;
        //Level等级从高到低,计算levelMoveSpan和update,currentNode会依次往后遍历
        for (int i = (int)currentLevel - 1; i >= 0; i--)
        {

            //初始化rank[i]为上一层的rank值,rank[i]记录在第curentLevel - 1 到 i层上移动的span值总和
            rank[i] = ((i + 1 == currentLevel) ? 0 : rank[i + 1]);
            //然后从当前的SkipListNode往后找,在第i层的Rank累加Span, 直到找到第一个比item大的才结束
            //把rank的所有层span值累加就是item的排名
            while (currentNode.LevelsInfo[i].Next != null && comparison(item, currentNode.LevelsInfo[i].Next.Item) > 0)
            {
                rank[i] += currentNode.LevelsInfo[i].Span;
                currentNode = currentNode.LevelsInfo[i].Next;
            }
            //记录在第i层结束的节点,恰好比item小,后续插入节点时需要更新needUpdate里的span等
            needUpdate[i] = currentNode;
        }

        //随机一个插入节点的层高
        uint newNodeLevel = RandomLevel();
        if (newNodeLevel > currentLevel)
        {
            for (int i = (int)currentLevel; i < newNodeLevel; i++)
            {
                //在大于等于currentLevel层上移动的span为0
                rank[i] = 0;
                //Header后续没有Node,表示跨了Length
                header.LevelsInfo[i].Next = null;
                header.LevelsInfo[i].Span = (uint)Count;

                //大于等于currentLevel层上结束的节点为Header
                needUpdate[i] = header;
            }
            currentLevel = newNodeLevel;
        }

        SkipListNode newNode = new SkipListNode(item, newNodeLevel);
        for (int i = 0; i < newNodeLevel; i++)
        {
            //在needUpdate[i] 和needUpdate[i].Next中间插入newNode
            newNode.LevelsInfo[i].Next = needUpdate[i].LevelsInfo[i].Next;
            needUpdate[i].LevelsInfo[i].Next = newNode;

            //设置newNode每层上跨越的span数
            newNode.LevelsInfo[i].Span = needUpdate[i].LevelsInfo[i].Span - (rank[0] - rank[i]);
            //修改needUpdate各层上的span,用第0层的rank减去第i层的rank可以计算得出
            needUpdate[i].LevelsInfo[i].Span = (rank[0] - rank[i]) + 1;
        }

        //大于newNode层高的needUpdate的Span需要加1
        for (int i = (int)newNodeLevel; i < currentLevel; i++)
        {
            needUpdate[i].LevelsInfo[i].Span++;
        }


        //记录newNode在第0层上的前一个Node
        newNode.Prev = (needUpdate[0] == header) ? null : needUpdate[0];
        //如果newNode在第0层上的下个节点非null,就修改下个节点的前置节点为newNode,否则说明newNode是最后一个节点,那么就更新Tail为newNode
        if (newNode.LevelsInfo[0].Next != null)
        {
            newNode.LevelsInfo[0].Next.Prev = newNode;
        }
        else
        {
            this.tail = newNode;
        }
        Count++;
    }

    private uint RandomLevel()
    {
        //为新的skiplist节点生成该节点level数目  
        uint level = 1;
        while (random.NextDouble() < 0.25d)
            level += 1;
        return (level < maxLevel) ? level : maxLevel;
    }


    public bool Remove(T item)
    {
        SkipListNode[] needUpdate = new SkipListNode[maxLevel];
        SkipListNode currentNode = header;
        // 遍历所有层,记录删除节点后需要被修改的节点到 update 数组  
        for (int i = (int)currentLevel - 1; i >= 0; i--)
        {
            while (currentNode.LevelsInfo[i].Next != null
                && comparison(item, currentNode.LevelsInfo[i].Next.Item) > 0)
                currentNode = currentNode.LevelsInfo[i].Next;
            needUpdate[i] = currentNode;
        }

        SkipListNode removeNode = currentNode.LevelsInfo[0].Next;
        if (removeNode != null && removeNode.Item.Equals(item))
        {
            DeleteNode(removeNode, needUpdate);
            return true;
        }
        return false;

    }

    private void DeleteNode(SkipListNode removeNode, SkipListNode[] update)
    {
        for (int i = 0; i < currentLevel; i++)
        {
            //update的下个节点是要移除的node的话,需要修改下Next,并合并span的值
            if (update[i].LevelsInfo[i].Next == removeNode)
            {
                //update[i]->level[i]的后继等于要删除节点x  
                update[i].LevelsInfo[i].Span += removeNode.LevelsInfo[i].Span - 1;
                update[i].LevelsInfo[i].Next = removeNode.LevelsInfo[i].Next;
            }
            else
            {
                update[i].LevelsInfo[i].Span -= 1;
            }
        }

        //更新第0层的前驱节点
        if (removeNode.LevelsInfo[0].Next != null)
        {
            removeNode.LevelsInfo[0].Next.Prev = removeNode.Prev;
        }
        else
        {
            //删除的是最后一个节点,需要更新tail
            this.tail = removeNode.Prev;
        }
        //收缩level,最少要有1层
        while (currentLevel > 1 && header.LevelsInfo[currentLevel - 1].Next == null)
            currentLevel--;
        Count--;
    }


    public uint GetIndex(T item)
    {
        SkipListNode currentNode = this.header;
        uint rank = 0;
        for (int i = (int)currentLevel - 1; i >= 0; i--)
        {
            while (currentNode.LevelsInfo[i].Next != null &&
                comparison(item, currentNode.LevelsInfo[i].Next.Item) >= 0)
            {
                rank += currentNode.LevelsInfo[i].Span;//排名,加上该层跨越的节点数目  
                currentNode = currentNode.LevelsInfo[i].Next;
            }

            if (currentNode.Item != null && currentNode.Item.Equals(item))
            {
                return rank;
            }
        }
        return 0;
    }

    public T GetItem(uint index)
    {

        uint traversed = 0;

        SkipListNode currentNode = this.header;
        for (int i = (int)currentLevel - 1; i >= 0; i--)
        {
            while (currentNode.LevelsInfo[i].Next != null && (traversed + currentNode.LevelsInfo[i].Span) <= index)
            {
                traversed += currentNode.LevelsInfo[i].Span;//排名  
                currentNode = currentNode.LevelsInfo[i].Next;
            }
            if (traversed == index)
            {
                return currentNode.Item;
            }
        }
        return null;
    }
    public List GetItems()
    {
        List rankList = new List();
        SkipListNode currentNode = this.header;
        while (currentNode.LevelsInfo[0].Next != null)
        {
            currentNode = currentNode.LevelsInfo[0].Next;
            rankList.Add(currentNode.Item);
        }
        return rankList;
    }
    public void RemoveRange(uint start, uint end, out List deleteList)
    {
        deleteList = new List((int)(end - start + 1));
        SkipListNode[] needUpdate = new SkipListNode[maxLevel];
        uint rank = 0;

        //找到start排名的update节点
        SkipListNode curretNode = this.header;
        for (int i = (int)currentLevel - 1; i >= 0; i--)
        {
            while (curretNode.LevelsInfo[i].Next != null && (rank + curretNode.LevelsInfo[i].Span) < start)
            {
                rank += curretNode.LevelsInfo[i].Span;//排名  
                curretNode = curretNode.LevelsInfo[i].Next;
            }
            needUpdate[i] = curretNode;
        }

        //到start节点
        rank++; //rank可能会小于start,也可能大于end(end为0)
        curretNode = curretNode.LevelsInfo[0].Next;

        //删除start到end之间的节点
        while (curretNode != null && rank <= end)
        {
            SkipListNode next = curretNode.LevelsInfo[0].Next;
            DeleteNode(curretNode, needUpdate);//删除节点 
            deleteList.Add(curretNode.Item);
            rank++;
            curretNode = next;
        }
    }
}

你可能感兴趣的:(数据结构与算法)