Count the height of a binary tree - algorithm

I want to caculate the height of a binary tree wihout using the algorithme that takes the maximum of the depths of each leaf.
This is the structure that I have on eache node
[content, left_son, right_son, father_node]
a list of arrays of size 4 that represents every node. the left_son, right_son, and father are respectively the indexes of the the left son node, the right son node and the father node in the list

This is indeed possible, but you have to rework your data structure a bit:
You can store a binary Tree in an array like this:
Store the value of the root node at index 0.
Store the left child of
a node at index 2*i+1, where i is the index of the current node;
right child goes at index 2*i+2.
If you do it like this
a node's parent is saved at index (i-1)/2.
your array needs the length 2^(h+1)-1, where h is the height of the tree.
So all you have to do ist keep track of the last "used" index in your array and use the above formula to calculate the height.
2^(h+1)-1 = l => h = ceil(ld(l+1))-1
whith l being the length of your array you effictively use and ld the logarithm with base 2.

Related

How to construct a binary tree from Leetcode values list?

For the following problem:
The output/correct result is specified as:
Output: [3,9,20,null,null,15,7]
I'm not sure what that output actually represents. I tried to scan it by level . E.g 3 is the root, then its children are 9 and 20 (which does not work). So then what is the actual tree?
It's how the binary tree is represented.
Output is a list of nodes where for node i (starting from index 0), node 2*i+1 is its left child and node 2*i+2 is its right child. So if those nodes do not exist, the corresponding value in the list is represented as NULL.
In this case, node 0 has a value of 3, and its left child is shown in node 1 (Output[1]) with value 9, while its right child is shown in node 2 (Output[2]) with value 20.
However, node 2 (Output[2] with value 20) does not have any children so the values corresponding to its children (Output[3], Output[4]) are shown as Null.

Exercise review Trees binary c++

Given a binary tree, whose root is located a treasure, and whose internal nodes can contain a dragon or does not contain anything, you are asked to design an algorithm that tells us the leaf of the tree whose path to the root has the lowest number of dragons. In the event that there are multiple paths with the same number of dragons, the algorithm will return that which is more to the left of all them. To do this, implement a function which gets a binary tree whose nodes store integers:
The root contains the integer 0, which represents the treasure.
The internal nodes contain the integer 1 to indicate that the node there is a dragon or the integer 2 to indicate that there is no dragon.
In each leaf stores an integer greater than or equal to 3 that cannot be repeated. and return the whole sheet to the path selected. The tree has at least one root node and a leaf node different from the root. For example, given the following tree (the second test case shown in the example), the algorithm return the integer 4.
I can not upload a picture of the tree of example, but someone tell me with words that I can do to go through all the branches, and to know which is the path with less dragons I'd appreciate it.
A greeting!
You want to think about these problems recursively: if you're at a parent node with...
no children you must have no dragon and a node counter, and you consider yourself to have 0 dragons and be the best node: you'd tell your parent that if asked
a left branch and/or a right branch, then you ask your children for their dragon-count and which node they consider best, and IF the left node reports a lesser or equal dragon count...
you take your best-node and dragon-count from it, ELSE
you take your best-node and dragon-count from the right node
then you add 1 to the dragon-count if your node's storing the integer 1
By starting that processing at the root node, you get the result for the entire tree.
This is the first algorithm that comes to mind. Assuming that you have an array that stores the values in nodes node_value[NODE_NUM], where NODE_NUM is the number of nodes in your tree, and you store index of childs of each node with the arrays left[NODE_NUM] and right[NODE_NUM], and your root will have index root_index. We will store information about the number of dragons in the path to root in the array dragon[NODE_NUM] So the algorithm pseudocode is:
# the recursive function itself
process(node_index):
n_left <- 0
if node_value[left[node_index]] = 1
n_left <- 1
n_right <- 0
if node_value[right[node_index]] = 1
n_right <- 1
dragon[left[node_index]] <- dragon[node_index] + n_left
dragon[right[node_index]] <- dragon[node_index] + n_right
process(left[node_index])
process(right[node_index])
# the number of dragons in path from root to root is, obviously, zero:
dragon[root_index] <- 0
# Call the function itself
process(root_index)
After that, in dragon we will have the number of dragons in the way to root from every nodes in tree. Now, all you have to do is to loop through all nodes and find the node that is a leaf and that its values is minimal:
min <- infinity
node_min <- unknown
for each node:
if node_value[node] >= 3:
if dragon[node] < min:
min <- dragon[node]
node_min <- node
return node_min
Now, the node_min is the node that has least dragons in the path to root.

How does the integers placed inside a tree structure? really confusing

So far i know that small value integers is placed at LHS and big value is placed at RHS. Can anyone give a good explanation. Thank you
Just to go over the background (skip this if you know it already):
A tree is a collection of nodes connected by edge with no loops allowed. The topmost node is called the root node. Nodes can have zero or more child nodes, which are nodes that extend downward from it. All nodes have exactly one parent node that extends upward from it (the root is the exception and has not parents). Allowing more than one parent would create loops, which are not allowed in trees.
A binary tree is a special type of tree where every node has at most two child nodes. All nodes in a binary tree have a value, a left pointer and a right pointer. The pointers point to the left and right child nodes, if they exist. If they don't exist, the pointers are NULL pointers don't point anywhere.
A binary search tree is a special type binary tree where the nodes are organized in a special way:
given any node, all nodes in its left subtree will have a lesser value
given any node, all nodes in its right subtree will have a greater value
Binary search trees are organized like this to allow for easy searching of values.
Now for the insertion algorithm...
Let's say we are given the number 3 to insert into the following tree:
6
/ \
4 9
/ \ /
2 5 8
All we need to do is start at the root and descend down the tree, going left if our new value less than the node value, and right if the our new value is greater. We stop when we find an empty space to insert out node.
So to insert the number 3...
start at the top node
3 is less than 6, so go left
3 is less than 4, so go left
3 is greater than 2, so go right
we've found empty space for a new node, so insert it here
6
/ \
4 9
/ \ /
2 5 8
\
3
The Insert() procedure can be defined recursively. Once we decide to move left or right, we can just focus on the subtree below the current node and forget about the rest of the tree.
In pseudocode:
Insert(Node root, int newValue)
if (root is empty)
Node N = new Node
N.value = newValue
else if (root.value < newValue)
Insert(root.left, newValue)
else if (root.value > newValue)
Insert(root.left, newValue)

Efficiently convert array to cartesian tree

I know how to convert an array to a cartesian tree in O(n) time
http://en.wikipedia.org/wiki/Cartesian_tree#Efficient_construction and
http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor#From RMQ to LCA
However, the amount of memory required is too high (constants) since I need to associate a left and right pointer at least with every node in the cartesian tree.
Can anyone link me to work done to reduce these constants (hopefully to 1)?
You do not need to keep the right and left pointers associated with your cartesian tree nodes.
You just need to keep the parent of each node and by the definition of cartesian tree
(A Cartesian Tree of an array A[0, N - 1] is a binary tree C(A) whose root is a minimum element of A, labeled with the position i of this minimum. The left child of the root is the Cartesian Tree of A[0, i - 1] if i > 0, otherwise there's no child. The right child is defined similary for A[i + 1, N - 1].), you can just traverse through this array and if the parent of the node has lower index than the node itself than the node will be the right son of its parent and similarly if the parent of the node has higher index than the node will be left son of its parent.
Hope this helps.
It is possible to construct a Cartesian tree with only extra space for child-to-parent references (by index): so besides the input array, you would need an array of equal size, holding index values that relate to the first array. If we call that extra array parentOf, then array[parentOf[i]] will be the parent of array[i], except when array[i] is the root. In that case parentOf[i] should be like a NIL pointer (or, for example, -1).
The Wikipedia article on Cartesian trees, gives a simple construction method:
One method is to simply process the sequence values in left-to-right order [...] in a structure that allows both upwards and downwards traversal of the tree
This may give the impression that it is necessary for that algorithm to maintain both upwards and downwards links in the tree, but this is not the case. It can be done with only maintaining links from child to parent.
During the construction, a new value is injected into the path that ends in the rightmost node (having the value that was most recently added). Any child in that path is by necessity a right child of its parent.
While walking up that path in the opposite direction, from the leaf, keep track of a parent and its right child (where you came from). Once you find the insertion point, that child will get the new node as parent, and the new child will get the "old" parent as its parent.
At no instance in this process do you need to store pointers to children.
Here is the algorithm written in JavaScript. As example, the tree is populated from the input array [9,3,7,1,8,12,10,20,15,18,5]. For verification only, both the input array and the parent references are printed:
class CartesianTree {
constructor() {
this.values = [];
this.parentOf = [];
}
extend(values) {
for (let value of values) this.push(value);
}
push(value) {
let added = this.values.length; // index of the new value
let parent = added - 1; // index of the most recently added value
let child = -1; // a NIL pointer
this.values.push(value);
while (parent >= 0 && this.values[parent] > value) {
child = parent;
parent = this.parentOf[parent]; // move up
}
// inject the new node between child and parent
this.parentOf[added] = parent;
if (child >= 0) this.parentOf[child] = added;
}
}
let tree = new CartesianTree;
tree.extend([9,3,7,1,8,12,10,20,15,18,5]);
printArray("indexes:", tree.values.keys());
printArray(" values:", tree.values);
printArray("parents:", tree.parentOf);
function printArray(label, arr) {
console.log(label, Array.from(arr, value => (""+value).padStart(3)).join(" "));
}
You can use a heap to store your tree, essentially it is an array where the first element int he array is the root, the second is the left child of the root the third the right, etc.. it is much cheaper but requires a little more care when programming it.
http://en.wikipedia.org/wiki/Binary_heap

Figuring a max repetitive sub-tree in an object tree

I am trying to solve a problem of finding a max repetitive sub-tree in an object tree.
By the object tree I mean a tree where each leaf and node has a name. Each leaf has a type and a value of that type associated with that leaf. Each node has a set of leaves / nodes in certain order.
Given an object tree that - we know - has a repetitive sub-tree in it.
By repetitive I mean 2 or more sub-trees that are similar in everything (names/types/order of sub-elements) but the values of leaves. No nodes/leaves can be shared between sub-trees.
Problem is to identify these sub-trees of the max height.
I know that the exhaustive search can do the trick. I am rather looking for more efficient approach.
you could implement a dfs traversal generating a hash value for each node. Store these values with the node height in a simple array. Sub-tree candidates are duplicate values, just check that the candidates are ok since two different sub-trees could yield same hash value.
Assuming the leafs and internal nodes are all of type Node and that standard access and traversal functions are available :
procedure dfs_update( node : Node, hashmap : Hashmap )
begin
if is_leaf(node) then
hashstring = concat("LEAF",'|',get_name_str(node),'|',get_type_str(node))
else // node is an internal node
hashstring = concat("NODE",'|',get_name_str(node))
for each child in get_children_sorted(node)
dfs_update(child,hashmap)
hashstring = concat(hashstring,'|',get_hash_string(hashmap,child))
end for
end if
// only a ref to node is added to the hashmap, we could also add
// the node's height, hashstring, whatever could be useful and inapropriate
// to keep in the Node ds
add(hashmap, hash(hashstring),node)
end
The tricky part is after a dfs_update, we have to get the list of collinding nodes in the hasmap by descending height and check two by two they are really repetitive.

Resources