I'm going to come right out and say that I am not the worlds greatest Mathematician :D So this problem may well be simple to most of you. Unfortunately it's confusing me and have had several stabs at a workable solutions.
As with any tree, one can have many branches, many branches can have more branches and so forth until they end with a leaf node. I've got information on each leaf that indicates its value.
What I require is a clear explination on how to tackle the problem of summarising each leaf node value as a total for it's branch (parent) and doing the same for the rest but not forgetting that if a branch is shared by other branches that it is the summary of each lower level branch and leaf that is directly related to itself.
To better explain:
Root
|----Branch
| |-Leaf 10
|----Branch
| |----Branch
| |-Leaf 20 |-Leaf 30
|----Branch |-Leaf 40
| |----Branch
| |----Branch
| |----Leaf 50
|-Leaf 60
The goal:
Root 210
|----Branch 10
| |-Leaf 10
|----Branch 90
| |----Branch 70
| |-Leaf 20 |-Leaf 30
|----Branch 50 |-Leaf 40
| |----Branch 50
| |----Branch 50
| |----Leaf 50
|-Leaf 60
I am able to identify the lowest level members (leaf nodes), the root node and the branches themselves. I don't have identification on whether or not the branch has other branches linked to itself lower down or directly linked to a leaf node. The relationship is very much bottom upwards to root. IE: The branch has no reference to who it's children are, but the children know who the parent is.
Please if something is unclear ask and I'll try and explain the problem better.
Any help would be appreciated.
OK, lefts give this a stab.
I would go about it like this with some pseudo code
foreach leaf in knownLeafs
parent = leaf.parent //get the leaf parent
parent.total = parent.total + leaf.value //add leaf value to parent total
while parent.parent != null //loop until no more parents, this would be the root
{
current = parent
parent = parent.parent //move up the structure
parent.total = parent.total + current.total
}
next leaf
you would need to create a function that will, given a node, return the parent node
node GetParentNodeFrom(node)
the new pseudo code would look something like this
foreach leaf in knownLeafs
parent = GetParentNodeFrom(leaf) //get the leaf parent
parent.total = parent.total + leaf.value //add leaf value to parent total
while GetParentNodeFrom(parent) != null //loop until no more parents, this would be the root
{
current = parent
parent = GetParentNodeFrom(current) //move up the structure
parent.total = parent.total + current.total
}
next leaf
Sorry, my mistake, you should only move the leaf value up, not the totals too.
See new leafValue used.
foreach leaf in knownLeafs
parent = GetParentNodeFrom(leaf) //get the leaf parent
leafValue = leaf.value
parent.total = parent.total + leafValue //add leaf value to parent total
while GetParentNodeFrom(parent) != null //loop until no more parents, this would be the root
{
current = parent
parent = GetParentNodeFrom(current) //move up the structure
parent.total = parent.total + leafValue
}
next leaf
You want to determine the sum of all the nodes in the tree?
Tree walking lends itself to an elegant recursive solution:
public int SumTree (TreeNode n) {
if(n.isLeafNode) return n.value;
return SumTree(n.left) + SumTree(n.right);
}
Assuming a binary tree.
Related
I'd like to know how to get the last child of a specific instance in JavaFX.
There is a simple way I know to get just the last child by subtracting 1 to the size of the list and assume that it returns at least a 0 value:
List<Node> children = getChildren();
int index = children.size() - 1;
Node lastChild = (index > -1) ? children.get(index) : null;
But I was looking for a specific instance, something like the :last-of-type selector in CSS.
I wanted to reflect a binary tree, such that all nodes on the left ended up on the right, and vice versa.
Something like :
A
/ \
B C
/ / \
D E F
would become
A
/ \
C B
/ \ \
F E D
I noticed that, while writing my solution, this code worked:
static Tree getReflection(Tree root) {
if(root == null) {
return null;
}
Tree reflect = root;
Tree subRight = getReflection(root.right);
Tree subLeft = getReflection(root.left);
reflect.left = subRight;
reflect.right = subLeft;
return reflect;
}
And yet, this one doesn't:
static Tree getReflection(Tree root) {
if(root == null) {
return null;
}
Tree reflect = root;
reflect.left = getReflection(root.right);
reflect.right = getReflection(root.left);
return reflect;
}
Can someone explain to me why? To me, they seem like identical methods, except one uses temporary tree variables.
Look at your first statement in each: when you assign
reflect = root
, the two variables now point to the same memory location. Now, let's look at the operation of the second routine:
Tree reflect = root;
// reflect and root now refer to exactly the same tree.
reflect.left = getReflection(root.right);
// reflect the right subtree; make that the new left subtree.
reflect.right = getReflection(root.left);
// Grab that new subtree, re-reflect it, and put it back on the right.
The original left subtree is lost, replaced by a reflection of the right.
In the first routine, you saved them in local variables until you'd done both reflections.
It is because in the second function (the one that doesn't work), you are assigning the reflected result to your left node and then using that as input to the reflection that you assign to your right node.
Tree reflect = root;
reflect.left = getReflection(root.right);
reflect.right = getReflection(root.left);
I have been given a dataset to work with that is layed out in the format of
Object | Type | Level | Comments | Parent | Child
So far I have been able to get the Object as the Parent Node and the Comments as a child node, however I need to get multiple children for this parent, and then children on them
An example of what I mean is like so
Object | Type | Level | Comments | Parent | Child
Dave | WH | 1 | comment | root | null
Simon | WH | 1 | comment | root | Fortnum
Simon | WH | 1 | comment | root | Mason
Tim | WH | 1 | comment | root | null
wallace| WH | 2 | comment | Simon | null
Mason | WH | 2 | comment | Simon | Mouse
Mouse | WH | 3 | comment | Mason | null
I need it to look like this
I have looked at the code from here Similar Stack Answer but its not working for me
I am pulling the sql data into a datatable and then looping through it to try and build the tree view.
This is the code that I am using that is only giving me the object as a parent node, and then the comment as a child node, but I need to be able to locate the actual children of the and then add them to the treeview.
For Each row As DataRow In dt.Rows
node = Searchnode(row.Item(4).ToString(), TreeView1)
If node IsNot Nothing Then
subNode = New TreeNode(row.Item(3).ToString())
node.ChildNodes.Add(subNode)
Else
node = New TreeNode(row.Item(0).ToString())
subNode = New TreeNode(row.Item(3).ToString())
node.ChildNodes.Add(subNode)
TreeView1.Nodes.Add(node)
End If
Next
then the function
Private Function Searchnode(ByVal nodetext As String, ByVal trv As TreeView) As TreeNode
For Each node As TreeNode In trv.Nodes
If node.Text = nodetext Then
Return node
End If
Next
End Function
Ive never really worked with treeviews before in ASP.Net but would be very grateful if anyone can help me.
Its not necessary to add child nodes when you add a new node. If the datatable is sorted the way your example shows the childnode will come up with a reference to its parent after the parent has already been added to the treeview.
so prior to this example edit the datatable and remove the duplicate objects
like remove one of the simons. the(child) column is not needed. also (optionally) going to add a reference to the parent when adding the child.
For Each row As DataRow In dt.Rows
node = Searchnode(row.Item(4).ToString(), TreeView1.Nodes)
If node IsNot Nothing Then
subNode = New TreeNode(row.Item(0).ToString()){ parent= node }
node.Nodes.Add(subNode)
Else 'root node
node = New TreeNode(row.Item(0).ToString())
TreeView1.Nodes.Add(node)
End If
Next
also searchnode needs to be recursive to check child nodes.
Private Function Searchnode(ByVal nodetext As String, ByVal tn As TreeNodeCollection) As TreeNode
TreeNode ret = nothing
For Each node As TreeNode In tn.Nodes
If node.Text = nodetext Then
ret = node
exit for
Else
ret = Searchnode(nodetext, node.Nodes)
End If
Next
Return ret
End Function
I'm creating a graph with nodes (with integer value) and edges (source, destination and weight) by reading a file with the format
1 51 1
1 72 2
1 77 1
etc.
Set<Node> nodes = new HashSet<Node>(); //a set of the nodes of a graph
ArrayList<Node> nodeList = new ArrayList<Node>();
ArrayList<Edge> edgeList = new ArrayList<Edge>();
...
Node node1=new Node(Integer.parseInt(temprelation[0]));
Node node2=new Node(Integer.parseInt(temprelation[1]));
nodes.add(node1);
nodes.add(node2);
Edge edge = new Edge(node1, node2, Integer.parseInt(temprelation[2]));
edgeList.add(edge);
}
The class Node has also a field "number of neighbors", and I wanted to go through all the edges and increment the number of neighbors whenever either source or destinatio appears.
for (int edge=0; edge<graph.getEdges().size(); edge++){
graph.getEdges().get(edge).getSource().neighborUp();
graph.getEdges().get(edge).getDestination().neighborUp();
}
Strangely enough, although the objects seem to be the same (I checked it with equals), the counter does not go up. E.g., for 1, it goes up once with the first edge, but does not go up when I try to increment it when the second edge is concerned. When considering the second edge before incrementing, it somehow shows the number of neighbors is 0, although I incremented the number of neighbors of the first node already in the first edge. So if I did printouts of counters before and after incrementation I always get 0 1 0 1 as if some other objects were concerned.
I assume that you use Java.
The problem is with creation of the graph, every time when you create an edge you create new objects for nodes:
Node node1=new Node(Integer.parseInt(temprelation[0]));
Node node2=new Node(Integer.parseInt(temprelation[1]));
The set contains only one copy for every Integer, but your edges contain different instancies.
To solve it you can create a map of all already parsed nodes and at every iteration instead of creating object from Integer, check if you have already created the object from Integer:
//one global object
Map<Integer,Node> map = new HashMap<Integer,Node> ();
...
Integer val = Integer.parseInt(temprelation[0]);
if (map.get(val)==null) {
map.put(val, new Node(val));
}
Node node1 = map.get(val);
val = Integer.parseInt(temprelation[1]);
if (map.get(val)==null) {
map.put(val, new Node(val));
}
Node node2 = map.get(val);
So I have a TreeView and it has about 7 parent nodes that have 3-5 children each. All of these children nodes when click navigate to a URL. What I would like to do is have one parent node auto-expand based on the URL and the other parent nodes to collapse.
If that wasn't clear, here is an example:
Root
|
|--Admin
| |
| |--Add.aspx
| |--Delete.aspx
|
|
|
|--Purchases
|
|--Orders.aspx
|--Stock.aspx
Lets say the user clicked on Orders.aspx, this would navigate them to that page, and when it does, I would want the tree view to collapse all parent nodes, and expand the current parent node. So Admin would be collapsed and Purchases would be expanded.
What I've attempted so far is this:
Protected Sub resize(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.TreeNodeEventArgs) Handles TreeView1.Load
For Each node As TreeNode In (CType(sender, TreeView)).Nodes
If node.NavigateUrl = GetCurrentPage() Then
For Each parentN As TreeNode In (CType(sender, TreeView)).Nodes
If Not (parentN.Parent.Selected = True And node.Parent.Text = parentN.Parent.Text) Then
parentN.Collapse()
Else : parentN.Expand()
End If
Next
End If
Next
End Sub
Public Shared Function GetCurrentPage() As String
Return System.IO.Path.GetFileName(HttpContext.Current.Request.Url.AbsolutePath).ToLower
End Function
I'm not really sure how to go about this.
Unless your tree is more complicated than you're describing, why won't this loop work?
For Each node As TreeNode In (CType(sender, TreeView)).Nodes
If node.NavigateUrl = GetCurrentPage() Then
node.Expand()
Else
node.Collapse()
End If
Next