public static bool Delete <T>(this Skiplist <T> skiplist, T key) { if (skiplist.Head == null) { return(false); } if (skiplist.Head.Down == null && skiplist.AreEqual(skiplist.Head.Key, key)) { return(TryRemoveCurrentHead(skiplist, key)); } var keyFound = skiplist.Find( key: key, pathAction: node => HandlePathToDeletionPoint(node, key, skiplist.MinimumGapSize, skiplist.AreEqual), origin: skiplist.Head.Down); if (skiplist.Head.Down.LengthOfList() <= 1) { skiplist.Head = skiplist.Head.Down; skiplist.Head.Up = null; } return(keyFound); }
public static bool Find <T>( this Skiplist <T> skiplist, T key, INode <T> origin = null, Action <INode <T> > pathAction = null) { var nodeOfKey = skiplist.FetchNode(key, origin, pathAction); return(skiplist.AreEqual(nodeOfKey.Key, key)); }
private static void InserterAction <T>(T key, Skiplist <T> skiplist, INode <T> pathNode) { if (pathNode.Down == null) { InsertKeyAfterNode(key, pathNode, skiplist.NodeFactory); } else if (pathNode.SizeOfGap() >= skiplist.MaximumGapSize) { SplitGap(pathNode, skiplist.NodeFactory); } }
private static bool TryRemoveCurrentHead <T>(Skiplist <T> skiplist, T key) { if (skiplist.Head.Right == skiplist.Head && skiplist.AreEqual(skiplist.Head.Key, key)) { skiplist.Head = null; return(true); } else { return(false); } }
private static string CreateFormatFor <T>(Skiplist <T> skiplist) { var bottomNodes = skiplist.Head.Bottom().EnumerateRight().ToList(); var numberOfColumns = bottomNodes.Count(); var columnWidth = bottomNodes.Max(node => node.Key.ToString().Length) + 1; var nodeFormat = Enumerable.Range(0, numberOfColumns).Select(i => "{" + i + ", -" + (columnWidth) + "}").ToArray(); var levelFormat = string.Concat(nodeFormat); return(levelFormat); }
public static string StringOf <T>(Skiplist <T> skiplist) { if (skiplist.Head == null) { return("Empty"); } else { var format = CreateFormatFor(skiplist); var levels = skiplist.Head.EnumerateDown(); var levelStrings = levels.Select(level => FormatLevel(level, format) + "\n").ToArray(); return(String.Concat(levelStrings)); } }
public static void Insert <T>(this Skiplist <T> skiplist, T key) { if (skiplist.Head == null) { skiplist.Head = skiplist.NodeFactory(key); skiplist.Head.ConnectTo(skiplist.Head); return; } skiplist.Find(key, pathAction: node => InserterAction(key, skiplist, node)); if (skiplist.Head.DistanceRightTo(skiplist.Head) > 1) { var newHead = skiplist.NodeFactory(skiplist.Head.Key); newHead.ConnectTo(newHead); newHead.ConnectDownTo(skiplist.Head); skiplist.Head = newHead; } }
public static Skiplist <T> CreateFrom <T>(IEnumerable <T> keys) { var keyList = keys.ToList(); var skiplist = new Skiplist <T>(MinimumGapSize); if (keyList.Any()) { var head = CreateOrderedCircularList(keyList, skiplist.NodeFactory); while (head.LengthOfList() > 1) { head = CreateNextLevel(head, skiplist.NodeFactory); } skiplist.Head = head; } return(skiplist); }
public static INode <T> FetchNode <T>( this Skiplist <T> skiplist, T key, INode <T> origin = null, Action <INode <T> > pathAction = null) { if (skiplist.Head == null) { return(null); } var node = origin ?? skiplist.Head; var atCorrectNode = false; while (!atCorrectNode) { node = FindCorrectGapInLevel(key, node, skiplist.InOrder, skiplist.AreEqual); if (pathAction != null) { pathAction(node); } if (node.Down != null) { node = node.Down; } else { atCorrectNode = true; } } return(node); }