/// <summary> /// Try to get a child node if it exists, else create a new internal child and return it /// </summary> /// <param name="rightChild"></param> /// <returns></returns> public GMacBinaryTree <T> GetOrAddInternalChildNode(bool rightChild) { Debug.Assert(TreeDepth > 1); if (rightChild) { var childNode = ChildNode1 as GMacBinaryTree <T>; if (!ReferenceEquals(childNode, null)) { return(childNode); } childNode = new GMacBinaryTree <T>(TreeDepth - 1); ChildNode1 = childNode; return(childNode); } else { var childNode = ChildNode0 as GMacBinaryTree <T>; if (!ReferenceEquals(childNode, null)) { return(childNode); } childNode = new GMacBinaryTree <T>(TreeDepth - 1); ChildNode0 = childNode; return(childNode); } }
public GMacBinaryTree <T> ResetInternalChildNode1() { var childNode = new GMacBinaryTree <T>(TreeDepth - 1); ChildNode1 = childNode; return(childNode); }
public GMacBinaryTree <T> FillFromTree <TU>(GMacBinaryTree <TU> sourceTree, Func <TU, T> valueConversionFunc) { if (TreeDepth != sourceTree.TreeDepth) { throw new InvalidOperationException("Tree depth mismatch"); } var sourceNodeStack = new Stack <GMacBinaryTree <TU> >(); var targetNodeStack = new Stack <GMacBinaryTree <T> >(); sourceNodeStack.Push(sourceTree); targetNodeStack.Push(this); while (sourceNodeStack.Count > 0) { var sourceNode = sourceNodeStack.Pop(); var targetNode = targetNodeStack.Pop(); if (sourceNode.HasChildNode1) { var sourceChildNode = sourceNode.ChildNode1; if (sourceChildNode.IsParentNode) { sourceNodeStack.Push(sourceChildNode as GMacBinaryTree <TU>); targetNodeStack.Push(targetNode.ResetInternalChildNode1()); } else { targetNode.ResetLeafChildNode1(valueConversionFunc(sourceChildNode.Value)); } } if (sourceNode.HasChildNode0) { var sourceChildNode = sourceNode.ChildNode0; if (sourceChildNode.IsParentNode) { sourceNodeStack.Push(sourceChildNode as GMacBinaryTree <TU>); targetNodeStack.Push(targetNode.ResetInternalChildNode0()); } else { targetNode.ResetLeafChildNode0( valueConversionFunc(sourceChildNode.Value) ); } } } return(this); }
public static DotGraph AddBinaryTree <T>(this DotGraph dotGraph, GMacBinaryTree <T> quadTree, bool showFullGraph) { var maxTreeDepth = quadTree.TreeDepth; var activeIDs = quadTree.LeafNodeIDs.ToArray(); var inactiveColor = DotColor.Rgb(Color.Gray); var activeColor = DotColor.Rgb(Color.Black); dotGraph.SetRankDir(DotRankDirection.LeftToRight); dotGraph.SetSplines(DotSplines.Spline); dotGraph.SetOverlap(DotOverlap.False); dotGraph.SetNodeMarginDelta(12); var nodeDefaults = dotGraph.AddNodeDefaults(); nodeDefaults.SetShape(DotNodeShape.Circle); nodeDefaults.SetStyle(DotNodeStyle.Solid); nodeDefaults.SetColor(inactiveColor); nodeDefaults.SetFontColor(inactiveColor); nodeDefaults.SetPenWidth(1.0f); var edgeDefaults = dotGraph.AddEdgeDefaults(); edgeDefaults.SetArrowHead(DotArrowType.Vee); edgeDefaults.SetStyle(DotEdgeStyle.Dashed); edgeDefaults.SetColor(inactiveColor); edgeDefaults.SetFontColor(inactiveColor); edgeDefaults.SetPenWidth(1.0f); var idsStack = new Stack <ulong>(); idsStack.Push(0ul); var treeDepthStack = new Stack <int>(); treeDepthStack.Push(maxTreeDepth); var dotNodeName = "".PadRight(maxTreeDepth, '-'); var dotNodeLabel = dotNodeName; var dotNode = dotGraph.AddNode(dotNodeName); dotNode.SetShape(DotNodeShape.DoubleCircle); dotNode.SetStyle(DotNodeStyle.Solid); dotNode.SetColor(activeColor); dotNode.SetFontColor(activeColor); dotNode.SetPenWidth(2.0f); dotNode.SetLabel(dotNodeLabel); while (idsStack.Count > 0) { var parentNodeId = idsStack.Pop(); var parentNodeTreeDepth = treeDepthStack.Pop(); dotNodeName = parentNodeTreeDepth == maxTreeDepth ? "".PadRight(parentNodeTreeDepth, '-') : parentNodeId.PatternToStringPadRight(maxTreeDepth, parentNodeTreeDepth); dotNode = dotGraph.AddNode(dotNodeName); var childNodesBitMask = 1ul << (parentNodeTreeDepth - 1); //Add child node 0 var childNodeId = parentNodeId; var isActive = childNodeId.IsActiveBinaryTreeNodeId(childNodesBitMask, activeIDs); if (showFullGraph || isActive) { AddChildNode( dotNode, childNodeId, parentNodeTreeDepth - 1, maxTreeDepth, isActive, activeColor ); if (parentNodeTreeDepth > 1) { idsStack.Push(childNodeId); treeDepthStack.Push(parentNodeTreeDepth - 1); } } //Add child node 1 childNodeId = parentNodeId | childNodesBitMask; isActive = childNodeId.IsActiveBinaryTreeNodeId(childNodesBitMask, activeIDs); if (showFullGraph || isActive) { AddChildNode( dotNode, childNodeId, parentNodeTreeDepth - 1, maxTreeDepth, isActive, activeColor ); if (parentNodeTreeDepth > 1) { idsStack.Push(childNodeId); treeDepthStack.Push(parentNodeTreeDepth - 1); } } } return(dotGraph); }