public void TreeSortTest() { // arrange AlgorithmBase <int> tree = new DataStructures.Tree <int>(items); // act tree.SortAndGetSpan(); // assert for (int i = 0; i < items.Count; i++) { Assert.AreEqual(sorted[i], tree.Items[i]); } }
/// <summary> /// Returns a spanning tree rooted at given node to find a shortest path from any node to the root node. /// </summary> public DataStructures.Tree <Node <TNodeValue, TLinkProperty> > AnyShortestPath(Node <TNodeValue, TLinkProperty> fromNode) { if (fromNode == null || fromNode.Graph != this) { throw new Exception("Arguments are incorrect"); } var treeNodes = new Dictionary <Node <TNodeValue, TLinkProperty>, bool>(); var treeLinks = new Dictionary <Link <TNodeValue, TLinkProperty>, bool>(); var tree = new DataStructures.Tree <Node <TNodeValue, TLinkProperty> >(fromNode); //resulting spanning tree if (NodesCount == 0) { return(tree); } treeNodes.Add(fromNode, false); var candidateLinks = new Dictionary <Link <TNodeValue, TLinkProperty>, bool>(); foreach (var l in fromNode.Links) { if (!l.IsLoop) { candidateLinks.Add(l, false); // add all links of fromNode to list } } foreach (var n in nodes) { n.Weight = 0; // reset weights of all nodes } while (true) { if (candidateLinks.Count == 0 || treeNodes.Count == NodesCount) { break; // all nodes are processed } // find a node not in the tree that has the smallest distance from starting node double smallestWeight = 0; Link <TNodeValue, TLinkProperty> closestLink = null; Node <TNodeValue, TLinkProperty> closestNode = null; foreach (var l in candidateLinks.Keys) { if (!candidateLinks[l]) { Node <TNodeValue, TLinkProperty> nodeInTree, nodeOutTree = null; if (treeNodes.ContainsKey(l.Node1)) { nodeInTree = l.Node1; nodeOutTree = l.Node2; } else { nodeInTree = l.Node2; nodeOutTree = l.Node1; } double newWeight = nodeInTree.Weight + l.Weight; if (closestLink == null || newWeight < smallestWeight) { closestLink = l; closestNode = nodeOutTree; smallestWeight = newWeight; } } } // if both nodes of the link are in the tree, mark the link as added if (closestNode == null) { break; } if (treeNodes.ContainsKey(closestNode)) { candidateLinks[closestLink] = true; } else { // add found node to the spanning tree, set its weight, add node's links that lead to a node not yet in the tree, to the candidate links closestNode.Weight = smallestWeight; treeNodes.Add(closestNode, false); foreach (var l in closestNode.Links) { var nodeNotInTree = l.Node1 == closestNode ? l.Node2 : l.Node1; if (!treeNodes.ContainsKey(nodeNotInTree) && !l.IsLoop && !candidateLinks.ContainsKey(l)) { candidateLinks.Add(l, false); } } var parent = tree.Root.FindNodeByValue(closestLink.Node1 == closestNode ? closestLink.Node2 : closestLink.Node1); parent.AddChild(closestNode); } } // check if all nodes have been added (the graph might not be connected) if (treeNodes.Count != this.NodesCount) { if (GraphType == GraphType.Undirected) { throw new Exception("Graph is not connected"); } else { throw new Exception("Not possible to follow all nodes"); } } return(tree); }