Sum node values towards the root node in a rooted tree - data-structures

Problem
I have a directed rooted tree where every node has some initial value. I would like every node's new value to equal the sum of both it and its descendants' initial values. I envisage this process as starting at leaf nodes and propagating values up the tree towards the root node.
By the end of the process, the root node's value should be the sum of all nodes; every other node has a lesser value accordingly; every leaf node has the value it started with (since there are no children to sum into it).
What is the best/most elegant way to perform this process on a given graph?
Data Structure
Just to clarify the directed rooted tree: it is a restrict form of a directed acyclic graph, where each node has at most 1 parent and there is a sole designated root node which doesn't have a parent.
In my implementation each node has a reference to its parent node (null for the root node) and an array of references to its child nodes (empty for leaf nodes).
Illustration
Initial tree and node values
Modified tree with updated node values
Failed attempt
My simple initial attempt starts with the leaf nodes, and for each one traverses the tree upwards, adding the running sum into its parent nodes until a bifurcating parent node is reached -- such a node is added as a candidate to begin with on the next iteration.
The problem this has is that certain bifurcating nodes can be summed into their own parent more than once, for example, if the paths from its own children to the relevant leaf nodes have a varying number of further bifurcating nodes.
List<Node> nodes = getLeaves();
HashSet<Node> nextNodes = new HashSet<>();
while (!nodes.isEmpty()) {
for (Node node : nodes) {
Node current = node;
while (current.degree < 2) { // terminate when reach bifurcating parent node
current.parent.value += current.value;
current = current.parent;
}
if (current.parent != null) { // skip root node
nextNodes.add(current.parent); // add bifurcating parent node for next iteration
}
}
nodes = new ArrayList<Node>(nextNodes);
nextNodes.clear();
}

Related

pick subset of nodes from a tree

Given a tree with n nodes each having some value in it.Find a subset of nodes such that the nodes picked in the subset has a maximum value and each node picked in the subset has even number of children.Here is a recursive solution that I thought of
func recurce(node)
if(node is null) return 0
exclude_current_node = sum of recurce of all node's children
//satisfy even number of child property
if(odd number of childeren's)
include_current_node = sum of recurce of all node's children except child with lowest value+value of node
else
include_current_node = sum of recurce of all node's children+value of node
return max(exclude_current_node,include_node)
Is this solution correct?
I can cache the result using dynamic programming to improve runtime.

How to find if a child node of a binary radix tree is an internal node or leaf node?

I am creating a binary radix tree(longest common prefix tree). The data is stored only in leaf nodes. The tree hierarchy has internal nodes and each internal node has two child nodes. A child node can either be a leaf node or internal node. Both leaf nodes and internal nodes store a reference to parent node.
Leaf nodes are stored in an array. internal nodes are stored in another array. Root node is first element of internal node array
Node
{
Node* parent;
}
LNode: Node
{
data;
}
INode: Node
{
Node* leftchild;
Node* rightchild;
}
Assuming that the tree structure is filled now as an array of internal nodes, if I now pick any internal node of the tree, how do I know whether the child node of the internal node is an internal node or leaf node ? to do this I am thinking of storing one Boolean variable for each child node to mark it as either a lead node or internal node. But this doesn't seem to me to be a good solution.
Can anyone suggest me a better way to do this ?

Inorder successor of BST without parent info

I was trying to find inorder successor for a node in a BST. And below is my sample code.
public TreeNode getInorderSuccesor(TreeNode t)
{
if(t == null)
{
return null;
}
if(t.getRight()!=null)
{
t = t.getRight();
while(t.getLeft()!=null)
{
t = t.getLeft();
}
return t;
}
else
{
TreeNode parent = t.getParent();
while(parent!=null && parent.getLeft() != t)
{
t = parent;
parent = t.getParent();
}
return parent;
}
}
Please let me know if any condition it will fail. And one more thing if some can share algo/ code/ sudocode for find the inorder successor without parent node. thanks!!!
Here is the basic logic for the successor function; the predecessor function is similar, but reversed. A recursive function descends the tree searching for the requested key, keeping track of the current tree as the possible successor every time if follows the left sub-tree. If it finds the key, its successor is the minimum element of the right sub-tree, found by chasing left sub-trees until reaching a null node. If the search reaches a null node and hence fails to find the key, the next largest key in the tree is the successor, found in the possible successor that was saved at each recursive call. I recently implemented this algorithm at my blog.
If the nodes in the tree have unique values, then it is quite simple. You just need to find:
The node with largest number that is smaller than or equal to the value of the node whose successor needs to be determined
The node with the smallest number that is strictly larger than the value of the node whose successor needs to be determined.
The latter node will be the answer. The first node can be used to check whether the input node is a valid node in the tree.
Pseudo-code:
function inOrderSuccessor(val, tree):
(left, right) = findRange(val, tree.rootnode, null, null)
if (left.val != val):
throw Error("No node with specified value")
return right
function findRange(val, currnode, left, right):
if (currnode == null):
return (left, right)
if (currnode.val <= val):
return findRange(val, currNode.right, currnode, right)
else:
return findRange(val, currNode.right, left, currnode)
If the nodes in the tree may have duplicate value, the in-order successor is not very well-defined. It is necessary to know when you are given a node, how do you differentiate between different nodes with the same value. Are you given a real reference to the node in the tree?
In the tricky case where you are simply given a reference to a node, and there are other nodes with the same value in the tree, then there are 2 cases:
Case 1: The node has right subtree, then you only need to find the smallest element in the right subtree.
Case 2: The node doesn't have right subtree. You need to check reference equality with all the nodes which has the same value. When you have found the node in the tree, traverse upward from the node back to root (you have this in the stack), and find the first node that does a left-turn.

Finding the lowest common ancestor of two nodes in a binary search tree - efficiently

Just wanted to know how efficient is the below algorithm to find the lowest common ancestor of two nodes in a binary search tree.
Node getLowestCommonAncestor (Node root, Node a, Node b) {
Find the in-order traversal of Node root.
Find temp1 = the in-order successor of Node a.
Find temp2 = the in-order successor of Node b.
return min (temp1, temp2);
}
Searching for the lowest common ancestor in a binary search tree is simpler than that: observe that the LCA is the node where the searches for item A and item B diverge for the first time.
Start from the root, and search for A and B at the same time. As long as both searches take you in the same direction, continue the search. Once you arrive at the node such that searching for A and B take you to different subtrees, you know that the current node is the LCA.
A node at the bottom of a large binary search trees can have an in-order successor close to it, for instance if it is the left child of a node, its in-order successor is its parent.
Two nodes descending from different children of the root will have the root as their least common ancestor, no matter where they are, so I believe that your algorithm gets this case wrong.
This is a discussion of efficient LCA algorithms (given time to build a preparatory data structure) at http://en.wikipedia.org/wiki/Lowest_common_ancestor, with pointers to code.
An inefficient but simple way of finding the LCA is as follows: in the tree keep pointers from children to parents and a note of the depth of each node. Given two nodes, move up from the deepest one until the depth if the same. If you are pointing at the other node, it is the LCA. Otherwise move up one step from each node and check again, and so on, until you meet at the LCA.
Finding LCA of BST is straight:
Find the node for which node1 and node2 are present on different
sides. But if the node1 is an ancestor of node2 than also we will
have to return node1. Below code implements this algo.
TreeNode<K> commonAncestor(TreeNode t, K k1, K k2){
if(t==null) return null;
while(true)
{
int c1=t.k.compareTo(k1);
int c2=t.k.compareTo(k2);
if(c1*c2<=0)
{
return t;
}
else
{
if(c1<0)
{
t = t.right;
}
else
{
t = t.left;
}
}
}
}

Algorithm for successor

I need an algorithm for returning the successor node of some arbitrary node of the
given binary search tree.
To give you an answer with the same level of detail as your question: Go up until going right is possible, and then left until you reach a leaf.
There are two general approaches:
If your binary tree nodes have pointers to their parent node, then you can traverse directly from the node to the successor node. You will have to determine how to use the parent pointers to do the traversal.
If your binary tree nodes do not have parent pointers, then you will have to do an inorder traversal of the tree starting at the root (presumably you have a root node pointer) and return the next node after the given node.
You need to maintain a zipper as you descend the tree. A zipper is simply a list of the nodes you have traversed, and for each an indication of whether you next went left or right.
It allows you to travel back up in the tree even if there aren't any pointers from children to parents.
The algorithm for successor is to go back (up in the zipper) as long as you were coming from the left, then go right once, and then descend to the leftmost child.
It's easier with a figure...
The successor of a node implies you are looking for an inorder successor.
The following method helps you determine the inorder successor WITHOUT ANY PARENT NODE OR EXTRA SPACE NON-RECURSIVELY
struct node * inOrderSuccessor(struct node *root, struct node *n)
{
//*If the node has a right child, return the smallest value of the right sub tree*
if( n->right != NULL )
return minValue(n->right);
//*Return the first ancestor in whose left subtree, node n lies*
struct node *succ=NULL;
while(root)
{
if(n->datadata < root->data)
{
succ=root; root=root->left;
}
else if(n->data > root->data)
root=root->right;
else break;
}
return succ;
}
I'm quite certain this is right. Do correct me if I am wrong. Thanks.

Resources