internal static FlattenerNode GetNodeByVisibleIndex(FlattenerNode root, int index) { root.TotalCount(); var flattenerNode = root; while (true) { for (; flattenerNode._left == null || index >= flattenerNode._left._totalCount; flattenerNode = flattenerNode._right) { if (flattenerNode._left != null) { index -= flattenerNode._left._totalCount; } if (flattenerNode.IsVisible) { if (index == 0) { return(flattenerNode); } --index; } } flattenerNode = flattenerNode._left; } }
private void ReplaceWith(FlattenerNode node) { if (_Parent != null) { if (_Parent._left == this) { _Parent._left = node; } else { _Parent._right = node; } if (node != null) { node._Parent = _Parent; } _Parent = null; } else { node._Parent = null; if (_treeFlattener == null) { return; } node._treeFlattener = _treeFlattener; _treeFlattener = null; node._treeFlattener._root = node; } }
private static FlattenerNode Rebalance(FlattenerNode node) { while (Math.Abs(node.Balance) > 1) { if (node.Balance > 1) { if (node._right.Balance < 0) { node._right = node._right.Rotate(); } node = node.LLRotate(); node._left = Rebalance(node._left); } else if (node.Balance < -1) { if (node._left.Balance > 0) { node._left = node._left.LLRotate(); } node = node.Rotate(); node._right = Rebalance(node._right); } } node._height = (byte)(1 + Math.Max(Height(node._left), Height(node._right))); node._totalCount = -1; return(node); }
protected void RemoveNodes(FlattenerNode start, FlattenerNode end) { var flattenerNodeList = new List <FlattenerNode>(); var node = start; FlattenerNode flattenerNode1; do { var flattenerNodeSet = new HashSet <FlattenerNode>(); for (var flattenerNode2 = end; flattenerNode2 != null; flattenerNode2 = flattenerNode2._Parent) { flattenerNodeSet.Add(flattenerNode2); } flattenerNodeList.Add(node); if (!flattenerNodeSet.Contains(node) && node._right != null) { flattenerNodeList.Add(node._right); node._right._Parent = null; node._right = null; } var flattenerNode3 = node.Successor(); DeleteNode(node); flattenerNode1 = node; node = flattenerNode3; } while (flattenerNode1 != end); var first = flattenerNodeList[0]; for (var index = 1; index < flattenerNodeList.Count; ++index) { first = ConcatTrees(first, flattenerNodeList[index]); } }
private static FlattenerNode ConcatTrees(FlattenerNode first, FlattenerNode second) { var pos = first; while (pos._right != null) { pos = pos._right; } InsertNodeAfter(pos, second); return(pos.GetListRoot()); }
private static void DeleteNode(FlattenerNode node) { FlattenerNode pos; if (node._left == null) { pos = node._Parent; node.ReplaceWith(node._right); node._right = null; } else if (node._right == null) { pos = node._Parent; node.ReplaceWith(node._left); node._left = null; } else { var node1 = node._right; while (node1._left != null) { node1 = node1._left; } pos = node1._Parent; node1.ReplaceWith(node1._right); node1._right = null; node1._left = node._left; node._left = null; node1._right = node._right; node._right = null; if (node1._left != null) { node1._left._Parent = node1; } if (node1._right != null) { node1._right._Parent = node1; } node.ReplaceWith(node1); if (pos == node) { pos = node1; } } node._height = 1; node._totalCount = -1; if (pos == null) { return; } RebalanceUntilRoot(pos); }
private FlattenerNode Rotate() { var right = _left._right; var left = _left; if (right != null) { right._Parent = this; } _left = right; left._right = this; left._Parent = _Parent; _Parent = left; left._right = Rebalance(this); return(left); }
private static void RebalanceUntilRoot(FlattenerNode pos) { for (; pos._Parent != null; pos = pos._Parent) { pos = pos != pos._Parent._left ? pos._Parent._right = Rebalance(pos) : pos._Parent._left = Rebalance(pos); } var flattenerNode = Rebalance(pos); if (flattenerNode == pos || pos._treeFlattener == null) { return; } flattenerNode._treeFlattener = pos._treeFlattener; pos._treeFlattener = null; flattenerNode._treeFlattener._root = flattenerNode; }
private FlattenerNode LLRotate() { var left = _right._left; var right = _right; if (left != null) { left._Parent = this; } _right = left; right._left = this; right._Parent = _Parent; _Parent = right; right._left = Rebalance(this); return(right); }
protected static void InsertNodeAfter(FlattenerNode pos, FlattenerNode newNode) { newNode = newNode.GetListRoot(); if (pos._right == null) { pos._right = newNode; newNode._Parent = pos; } else { pos = pos._right; while (pos._left != null) { pos = pos._left; } pos._left = newNode; newNode._Parent = pos; } RebalanceUntilRoot(pos); }
internal static int GetVisibleIndexForNode(FlattenerNode node) { var num = node._left?.TotalCount() ?? 0; for (; node._Parent != null; node = node._Parent) { if (node == node._Parent._right) { if (node._Parent._left != null) { num += node._Parent._left.TotalCount(); } if (node._Parent.IsVisible) { ++num; } } } return(num); }
private static void DumpTree(FlattenerNode node) { node.GetListRoot().DumpTree(); }
private static int Height(FlattenerNode node) { return(node?._height ?? 0); }
public Flattener(FlattenerNode root) { root = root.GetListRoot(); _root = root; root._treeFlattener = this; }