/// <summary> /// Adds the child node to the child tree of the current node on the path provided. /// </summary> /// <param name="currentNode"></param> /// <param name="path"></param> /// <param name="childNode"></param> /// <remarks> /// We do the following: /// /// 1. If the child node on path for the current node is null assign childNode to it. /// /// 2. Other wise continue to try a recursive insert on our child node on the path. /// </remarks> private void AddToChildTree(Node currentNode, Node.ChildPath path, Node childNode) { if (currentNode.Children[(int)path] == null) { currentNode.Children[(int)path] = childNode; childNode.Parent = currentNode; } else { RecursiveInsert(currentNode.Children[(int)path], childNode); } }
/// <summary> /// Removes a node from the tree. /// </summary> /// <param name="node"></param> /// <remarks> /// We remove a node using the following algorithm: /// /// 1. If the node has no children set the parents child to null. /// /// 2. If we have a left child but no right child set the parents child to the left child. /// /// 2. If we have a right child but no left child set the parents child to the right child. /// /// 3. If we have both children set out parents child to our Node.ChildPath.Behind child. /// Do a depth first insert of all children of the current node to rebuild the tree with /// Node.ChildPath.Behind as the current parent. /// </remarks> private void RemoveNode(Node node) { Node newChild = null; if (node.Children[(int)Node.ChildPath.Behind] != null && node.Children[(int)Node.ChildPath.InfrontOrEqual] != null) { List <Node> toInsert = new List <Node>(); newChild = node.Children[(int)Node.ChildPath.Behind]; List <Node> toCheck = new List <Node>(); while (toCheck.Count > 0) { Node currentNode = toCheck[0]; toCheck.RemoveAt(0); if (currentNode != node && currentNode != newChild) { toInsert.Add(currentNode); } if (currentNode.Children[(int)Node.ChildPath.Behind] != null) { toCheck.Add(currentNode.Children[(int)Node.ChildPath.Behind]); } if (currentNode.Children[(int)Node.ChildPath.InfrontOrEqual] != null) { toCheck.Add(currentNode.Children[(int)Node.ChildPath.InfrontOrEqual]); } } newChild.Parent = null; newChild.Children[(int)Node.ChildPath.Behind] = null; newChild.Children[(int)Node.ChildPath.InfrontOrEqual] = null; foreach (Node oldNode in toInsert) { //Break the old child links. oldNode.Parent = null; oldNode.Children[0] = null; oldNode.Children[1] = null; RecursiveInsert(newChild, oldNode); } } else if (node.Children[(int)Node.ChildPath.Behind] == null && node.Children[(int)Node.ChildPath.InfrontOrEqual] != null) { newChild = node.Children[(int)Node.ChildPath.InfrontOrEqual]; } else if (node.Children[(int)Node.ChildPath.Behind] != null && node.Children[(int)Node.ChildPath.InfrontOrEqual] == null) { newChild = node.Children[(int)Node.ChildPath.Behind]; } if (node.Parent != null) { Node.ChildPath side = node.Parent.Children[(int)Node.ChildPath.Behind] == node ? Node.ChildPath.Behind : Node.ChildPath.InfrontOrEqual; node.Parent.Children[(int)side] = newChild; if (newChild != null) { newChild.Parent = node.Parent; } } else { if (newChild != null) { newChild.Parent = null; } m_RootNode = newChild; } }