/// <summary> /// Конструктор /// </summary> /// <param name="info">Информация хранящайся в узле дерева</param> /// <param name="prioryty">Приоритет вершины</param> /// <param name="left">Левый сын</param> /// <param name="right">Правый сын</param> public NodeOfCartesianTree(TNode info, int prioryty, NodeOfCartesianTree <TNode, TValue> left = null, NodeOfCartesianTree <TNode, TValue> right = null) { Info = info; Priority = prioryty; Left = left; Right = right; }
/// <summary> /// Конструктор /// </summary> /// <param name="info">Информация хранящайся в узле дерева</param> /// <param name="left">Левый сын</param> /// <param name="right">Правый сын</param> public NodeOfCartesianTree(TNode info = null, NodeOfCartesianTree <TNode, TValue> left = null, NodeOfCartesianTree <TNode, TValue> right = null) { Info = info; Priority = random.Next(int.MinValue, int.MaxValue); Left = left; Right = right; }
/// <summary> /// Разделяет текущее декратовое дерева на два по ключу x /// Все элементы с ключом не превосходящим х останутся в текущем дерева /// Остальные окажутся в поддереве, которое возвращает функция /// </summary> /// <param name="x">Ключ, по которому происходит разделение</param> /// <returns>Поддерево, в котором ключи больше x</returns> public Treap <TNode, TValue> Split <T>(T x) { NodeOfCartesianTree <TNode, TValue> l = null, r = null; Root?.Split(x, out l, out r, Logs); Root = l; return(new Treap <TNode, TValue>(r)); }
/// <summary> /// Конструктор /// </summary> /// <param name="value">Значение текщуего узла</param> public NodeOfCartesianTree(TValue value) { Info = new TNode { Value = value }; Priority = random.Next() % (MaxPriority - MinPriority + 1) + MinPriority; Left = null; Right = null; }
/// <summary> /// Ищет объект NodeDrawer по узлу Декартового дерева /// </summary> /// <param name="node">Узел Декартового дерева</param> /// <returns>Найденный NodeDrawer</returns> public NodeDrawer FindNodeDrawer(NodeOfCartesianTree <TNode, TValue> node) { for (int i = 0; i < Nodes.Count; ++i) { if (Nodes[i] == node) { return(NodeDrawers[i]); } } return(null); }
/// <summary> /// Ковертирует узел декартового дерева в узел для отрисовки на форме /// </summary> /// <param name="node">Узел декартового дерева</param> /// <param name="startY">Высота рисования узла</param> /// <param name="startX">Начало области рисования узла</param> /// <param name="endX">Конец области рисования узла</param> /// <returns></returns> private NodeDrawer GetNodeDrawer(NodeOfCartesianTree <TNode, TValue> node, int startY, int startX, int endX) { NodeDrawer nodeDrawer = new NodeDrawer() { StartY = startY, StartX = startX, EndX = endX, Text = node.ToString(), Size = Size, PenBorder = (Pen)PenBorder.Clone(), BrushFont = (Brush)BrushFont.Clone(), MinSizeForOutText = Size, Font = Font }; return(nodeDrawer); }
/// <summary> /// Разделяет текущее дерево по ключу x (в левом дереве все что меньше x, в правом остальные) /// </summary> /// <param name="x">Ключ, по которому происходит разделение</param> /// <param name="left">Получивщееся левое поддереов</param> /// <param name="right">Получившееся правое поддерево</param> /// <param name="logs">Информация о проведенных операциях</param> public void SplitLeft <T>(T x, out NodeOfCartesianTree <TNode, TValue> left, out NodeOfCartesianTree <TNode, TValue> right, List <LogTreap <TNode, TValue> > logs) { NodeOfCartesianTree <TNode, TValue> newTree = null; logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.StartSplite, this)); if (Info.Value.CompareTo(x) < 0) { if (Right == null) { right = null; } else { logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.RemoveEdge, Right)); Right.SplitLeft(x, out newTree, out right, logs); } if (newTree != null) { logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.AddedEdge, this, newTree)); } Right = newTree; left = this; } else { if (Left == null) { left = null; } else { logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.RemoveEdge, Left)); Left.SplitLeft(x, out left, out newTree, logs); } if (newTree != null) { logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.AddedEdge, this, newTree)); } Left = newTree; right = this; } Update(); logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.EndSplite, this)); }
/// <summary> /// Операция слияния двух декартовых деревеьев /// Ключи правого поддерева не меньше, чем ключи левого поддерева /// </summary> /// <param name="left">Левое поддерево</param> /// <param name="right">Правое поддерево</param> /// <param name="logs">Информация о проведенных операциях</param> /// <returns>Результирующее дерево</returns> public static NodeOfCartesianTree <TNode, TValue> Merge( NodeOfCartesianTree <TNode, TValue> left, NodeOfCartesianTree <TNode, TValue> right, List <LogTreap <TNode, TValue> > logs ) { if (left == null) { return(right); } if (right == null) { return(left); } logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.StartMerge, left, right)); if (left.Priority > right.Priority) { if (left.Right != null) { logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.RemoveEdge, left.Right)); } var newRight = Merge(left.Right, right, logs); logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.AddedEdge, left, newRight)); left.Right = newRight; left.Update(); logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.EndMerge, left, right)); return(left); } else { if (right.Left != null) { logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.RemoveEdge, right.Left)); } var newLeft = Merge(left, right.Left, logs); logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.AddedEdge, right, newLeft)); right.Left = newLeft; right.Update(); logs?.Add(new LogTreap <TNode, TValue>(LogTreapEvent.EndMerge, left, right)); return(right); } }
/// <summary> /// Операция слияния декартового дерева с subTree /// Ключи subTree не меньше, чем ключи текущего дерева /// </summary> /// <param name="subTree">Поддерево, с которым происходит слияние</param> public void Merge(Treap <TNode, TValue> subTree) { Root = NodeOfCartesianTree <TNode, TValue> .Merge(Root, subTree.Root, Logs); }
/// <summary> /// Конструктор /// </summary> /// <param name="rootNode">Корень дерева</param> /// <param name="enableLogging">Ведение логов</param> public Treap(NodeOfCartesianTree <TNode, TValue> rootNode, bool enableLogging = false) : this(enableLogging) { Root = rootNode; }
/// <summary> /// Конструктор /// </summary> /// <param name="rootInfo">Информация, которая хранится в корне</param> /// <param name="enableLogging">Ведение логов</param> public Treap(TNode rootInfo, bool enableLogging = false) : this(enableLogging) { Root = new NodeOfCartesianTree <TNode, TValue>(rootInfo); }
/// <summary> /// Конструктор /// </summary> /// <param name="value">Информация, которая хранится в корне</param> /// <param name="enableLogging">Ведение логов</param> public Treap(TValue value, bool enableLogging = false) : this(enableLogging) { Root = new NodeOfCartesianTree <TNode, TValue>(value); }