コード例 #1
0
ファイル: SkipList.cs プロジェクト: htoma/algorithms
        public SkipList(int maxLevels = MAX_LEVELS)
        {
            _maxLevels = maxLevels >= 1 && maxLevels <= MAX_LEVELS ? maxLevels : MAX_LEVELS;
            _head = new Node(int.MinValue + 1, maxLevels);
            _head.LevelNodes[0] = new LevelNode(_head);

            _random = new Random();
            _currentMaxLevels = 0;
        }
コード例 #2
0
ファイル: SkipList.cs プロジェクト: htoma/algorithms
        public void Insert(int value)
        {
            var map = new Dictionary<int, int> { { 1, 1 }, { 2, 2 }, { 7, 1 }, { 9, 2 }, { 10, 3 } };

            // logN operation
            int nodeLevels = generateRandomLevelCount(); //map[value];

            // avoid going beyond the current max levels
            if (nodeLevels > _currentMaxLevels)
            {
                _head.LevelNodes[_currentMaxLevels] = new LevelNode(_head);

                // increase the current max level
                _currentMaxLevels++;
                nodeLevels = _currentMaxLevels;
            }

            var node = new Node(value, nodeLevels);

            // start scanning from the highest level accessible to this node
            // need to update later on the skipped nodes for each level
            // and the next for each node on each level
            // we cannot do that unless we know how many level 0 nodes were actually skipped

            var skippedNodesMap = new Dictionary<int, dynamic>();
            var countSkippedPerLevel = new int[_currentMaxLevels];
            LevelNode pointer = _head.LevelNodes[_currentMaxLevels - 1];

            for (var level = _currentMaxLevels - 1; level >= 0; level--)
            {
                pointer = pointer.ParentNode.LevelNodes[level];

                countSkippedPerLevel[level] = 0;
                while (pointer.Next != null)
                {
                    if (pointer.Next.Value > value)
                    {
                        // no need to step away, found our node
                        break;
                    }

                    pointer = pointer.Next;

                    // if we are on the highest level and moving, it means we haven't found the anchor point
                    if (level != _currentMaxLevels - 1)
                    {
                        countSkippedPerLevel[level] += pointer.SkippedNodes + 1;
                    }
                }

                if (level < nodeLevels)
                {
                    // create node if needed
                    var levelNode = new LevelNode(node);
                    levelNode.Next = pointer.Next;
                    node.LevelNodes[level] = levelNode;
                    pointer.Next = levelNode;

                    // will have to update the skipped nodes for this node
                    skippedNodesMap[level] = new {
                                                     IsNew = true,
                                                     Node = levelNode
                                                 };

                    if (level > 0)
                    {
                        // we'll update this value later
                        levelNode.SkippedNodes = 0;
                    }
                    else
                    {
                        // update values for upper levels
                        for (int i = 1; i < _currentMaxLevels; i++)
                        {
                            dynamic toUpdate = skippedNodesMap[i];
                            LevelNode nodeToUpdate = toUpdate.Node;
                            if (toUpdate.IsNew)
                            {
                                nodeToUpdate.SkippedNodes = nodeToUpdate.ParentNode.LevelNodes[i - 1].SkippedNodes +
                                    countSkippedPerLevel[i - 1];
                                if (nodeToUpdate.Next != null)
                                {
                                    nodeToUpdate.Next.SkippedNodes = nodeToUpdate.Next.SkippedNodes -
                                                                     nodeToUpdate.SkippedNodes;
                                }
                            }
                            else
                            {
                                if (nodeToUpdate.Next != null)
                                {
                                    nodeToUpdate.Next.SkippedNodes += 1;
                                }
                            }
                        }
                    }
                }
                else
                {
                    skippedNodesMap[level] = new
                                                 {
                                                     IsNew = false,
                                                     Node = pointer
                                                 };
                }
            }
        }