How many non-isomorphic full binary trees can n nodes generate? - algorithm

Isomorphism means that arbitary sub-trees of a full binary tree swapping themselves can be identical to another one.
The answer is definitely not Catalan Number, because the amount of Catalan Number counts the isomorphic ones.

I assume by n nodes you mean n internal nodes. So it will have 2n+1 vertices, and 2n edges.
Next, we can put an order on binary trees as follows. A tree with more nodes is bigger. If two trees have the same number of nodes, compare the left side, and break ties by comparing the right. If two trees are equal in this order, it isn't hard to show by induction that they are the same tree.
For your problem, we can assume that for each isomorphism class we are only interested in the maximal tree in that isomorphism class. Note that this means that both the left and the right subtrees must also be maximal in their isomorphism classes, and the left subtree must be the same as or bigger than the right.
So suppose that f(n) is the number of non-isomorphic binary trees with n nodes. We can now go recursively. Here are our cases:
n=0 there is one, the empty tree.
n=1 there is one. A node with 2 leaves.
n > 1. Let us iterate over m, the number on the right. If 2m+1 < n then there are f(m) maximal trees on the right, f(n-m-1) on the left, and all of those are maximal for f(m) * f(n-m-1). If 2m+1 = n then we want a maximal tree on the right with m nodes, and a maximal tree on the left with m nodes, and the one on the right has to be smaller than or equal to the one on the left. But there is a well-known formula for how many ways to do that, which is f(m) * (f(m) + 1) / 2. And finally we can't have n < 2m+1 because in that case we don't have a maximal tree.
Using this, you should be able to write a recursive function to calculate the answer.
UPDATE Here is such a function:
cache = {0: 1, 1:1}
def count_nonisomorphic_full_trees (n):
if n not in cache:
answer = 0
for m in range(n):
c = count_nonisomorphic_full_trees(m)
if n < m+m+1:
break
elif n == m+m+1:
answer = answer + c*(c+1)//2
else:
d = count_nonisomorphic_full_trees(n-m-1)
answer = answer + c*d
cache[n] = answer
return cache[n]
Note that it starts off slower than the Catalan numbers but still grows exponentially.

Related

Running time of algorithm with arbitrary sized recursive calls

I have written the following algorithm that given a node x in a Binary Search Tree T, will set the field s for all nodes in the subtree rooted at x, such that for each node, s will be the sum of all odd keys in the subtree rooted in that node.
OddNodeSetter(T, x):
if (T.x == NIL):
return 0;
if (T.x.key mod 2 == 1):
T.x.s = T.x.key + OddNodeSetter(T, x.left) + OddNodeSetter(T, x.right)
else:
T.x.s = OddNodeSetter(T, x.left) + OddNodeSetter(T, x.right)
I've thought of using the master theorem for this, with the recurrence
T(n) = T(k) + T(n-k-1) + 1 for 1 <= k < n
however since the size of the two recursive calls could vary depending on k and n-k-1 (i.e. the number of nodes in the left and right subtree of x), I can't quite figure out how to solve this recurrence though. For example in case the number of nodes in the left and right subtree of x are equal, we can express the recurrence in the form
T(n) = 2T(n/2) + 1
which can be solved easily, but that doesn't prove the running time in all cases.
Is it possible to prove this algorithm runs in O(n) with the master theorem, and if not what other way is there to do this?
The algorithm visits every node in the tree exactly once, hence O(N).
Update:
And obviously, a visit takes constant time (not counting the recursive calls).
There is no need to use the Master theorem here.
Think of the problem this way: what is the maximum number of operations you have do for each node in the tree? It is bounded by a constant. And what the is the number of nodes in the tree? It is n.
The multiplication of constant with n is still O(n).

Proof that a binary tree with n leaves has a height of at least log n

I've been able to create a proof that shows the maximum total nodes in a tree is equal to n = 2^(h+1) - 1 and logically I know that the height of a binary tree is log n (can draw it out to see) but I'm having trouble constructing a formal proof to show that a tree with n leaves has "at least" log n. Every proof I've come across or been able to put together always deals with perfect binary trees, but I need something for any situation. Any tips to lead me in the right direction?
Lemma: the number of leaves in a tree of height h is no more than 2^h.
Proof: the proof is by induction on h.
Base Case: for h = 0, the tree consists of only a single root node which is also a leaf; here, n = 1 = 2^0 = 2^h, as required.
Induction Hypothesis: assume that all trees of height k or less have fewer than 2^k leaves.
Induction Step: we must show that trees of height k+1 have no more than 2^(k+1) leaves. Consider the left and right subtrees of the root. These are trees of height no more than k, one less than the height of the whole tree. Therefore, each has at most 2^k leaves, by the induction hypothesis. Since the total number of leaves is just the sum of the numbers of leaves of the subtrees of the root, we have n = 2^k + 2^k = 2^(k+1), as required. This proves the claim.
Theorem: a binary tree with n leaves has height at least log(n).
We have already noted in the lemma that the tree consisting of just the root node has one leaf and height zero, so the claim is true in that case. For trees with more nodes, the proof is by contradiction.
Let n = 2^a + b where 0 < b <= 2^a. Now, assume the height of the tree is less than a + 1, contrary to the theorem we intend to prove. Then the height is at most a. By the lemma, the maximum number of leaves in a tree of height a is 2^a. But our tree has n = 2^a + b > 2^a leaves, since 0 < b; a contradiction. Therefore, the assumption that the height was less than a+1 must have been incorrect. This proves the claim.

How to form a recurrence for findng the height of a weight balanced binary tree?

A weight balanced tree is a binary tree in which for each node, the no. of nodes in the left subtree is atleast half and at most twice the no. of nodes in the right sub tree. So how to approach for forming a recurrence for finding the height of this weight balanced binary tree ?
Only full binary trees can be weight-balanced. Let H(n) be the maximum height of a weight-balanced binary tree with exactly n interior nodes (so, 2*n+1 nodes). The base case
H(0) = 0
is obvious. The recurrence
floor((4*n/3-1)/2)
H(n) = 1 + max max(H(l), H(n-1-l)) for all n > 0
l=ceiling((2*n/3-1)/2)
follows from the recurrence for height and the fact that, given n-1 interior nodes that are not the root, we must distribute them between the left (l) and the right (n-1-l) subtrees, subject to the weight-balance criterion. (There are 2*n interior and exterior nodes to distribute; the most unbalanced split possible is one-third/two-thirds; a full binary tree with k nodes has (k-1)/2 interior nodes.)
Let's conjecture that H(n) is nondecreasing and write a new recurrence
H'(0) = 0
H'(n) = 1 + H'(floor(2*n/3-1/2)) for all n > 0.
The point of the new recurrence is that, if it is in fact nondecreasing, then H(n) = H'(n), by an strong induction proof that involves simplifying the maxes in the other recurrence. In fact, we can prove by induction without solving H'(n) that it is, in fact, nondecreasing, so this simplification is fine.
As for solving H'(n), I'll wave my hands and tell you that Akra--Bazzi applies (alternatively, the Master Theorem Case 2 if you want to play fast and loose with the floor), yielding the asymptotic bound H'(n) = Theta(log n).

All pairs shortest path in a connected graph with N nodes and N-1 edges

I have a graph with N nodes (2 <= N <= 50000) and N is even. The values of the Nodes are always a number between 1 and N/2. It's granted that there is only one path between any pair of nodes and the weight of the edges is always one. How can i sum the distance of all nodes with equal value ?
This is a example:
The number inside the square is the value of the node and the small number below it its the identification of the node.
In this example the sum is distance(1,6) + distance(2,5) + distance(3,4) = 5
Floyd-Marshall or simple BFS its to expensive for this case.
I've seen that on DAGs is possible to get the shortest path with a topological sort. In this case it is a good approach ?
I'm assuming here that you have a disjoint partition of your node set into pairs, represented by numbers from 1 to N/2. I'm also assuming that by "there is only one path between any pair of nodes" you really mean any pair and not just those of the same color.
In that case, first realize that your graph is a tree. So root it arbitrarily, and traverse it in depth-first order to compute the depth of all nodes. Note that for two nodes x and y, if their lowest common ancestor is l, then
distance(x, y) = distance(x, l) + distance(y, l)
= depth(x) - depth(l) + depth(y) - depth(l)
= depth(x) + depth(y) - 2*depth(l)
You can use Tarjan's off-line LCA algorithm to compute the LCA of all your pairs in (almost) linear time and compute the distances. You don't even need to store the LCAs in this case.
Runtime: O(n * α(n)) with naive disjoint set union, O(n) with the improvements from "A Linear-Time Algorithm for a Special Case of
Disjoint Set Union", Gabow & Tarjan, 1983

binary tree data structures

Can anybody give me proof how the number of nodes in strictly binary tree is 2n-1 where n is the number of leaf nodes??
Proof by induction.
Base case is when you have one leaf. Suppose it is true for k leaves. Then you should proove for k+1. So you get the new node, his parent and his other leaf (by definition of strict binary tree). The rest leaves are k-1 and then you can use the induction hypothesis. So the actual number of nodes are 2*(k-1) + 3 = 2k+1 == 2*(k+1)-1.
just go with the basics, assuming there are x nodes in total, then we have n nodes with degree 1(leaves), 1 with degree 2(the root) and x-n-1 with degree 3(the inner nodes)
as a tree with x nodes will have x-1 edges. so summing
n + 3*(x-n-1) + 2 = 2(x-1) (equating the total degrees)
solving for x we get x = 2n-1
I'm guessing that what you really want is something like a proof that the depth is log2(N), where N is the number of nodes. In this case, the answer is fairly simple: for any given depth D, the number of nodes is 2D.
Edit: in response to edited question: the same fact pretty much applies. Since the number of nodes at any depth is 2D, the number of nodes further up the tree is 2D-1 + 2D-2 + ...20 = 2D-1. Therefore, the total number of nodes in a balanced binary tree is 2D + 2D-1. If you set n = 2D, you've gone the full circle back to the original equation.
I think you are trying to work out a proof for: N = 2L - 1 where L is the number
of leaf nodes and N is the total number of nodes in a binary tree.
For this formula to hold you need to put a few restrictions on how the binary
tree is constructed. Each node is either a leaf, which means it has no children, or
it is an internal node. Internal nodes have 3
possible configurations:
2 child nodes
1 child and 1 internal node
2 internal nodes
All three configurations imply that an internal node connects to two other nodes. This explicitly
rules out the situation where node connects to a single child as in:
o
/
o
Informal Proof
Start with a minimal tree of 1 leaf: L = 1, N = 1 substitute into N = 2L - 1 and the see that
the formula holds true (1 = 1, so far so good).
Now add another minimal chunk to the tree. To do that you need to add another two nodes and
tree looks like:
o
/ \
o o
Notice that you must add nodes in pairs to satisfy the restriction stated earlier.
Adding a pair of nodes always adds
one leaf (two new leaf nodes, but you loose one as it becomes an internal node). Node growth
progresses as the series: 1, 3, 5, 7, 9... but leaf growth is: 1, 2, 3, 4, 5... That is why the formula
N = 2L - 1 holds for this type of tree.
You might use mathematical induction to construct a formal proof, but this works find for me.
Proof by mathematical induction:
The statement that there are (2n-1) of nodes in a strictly binary tree with n leaf nodes is true for n=1. { tree with only one node i.e root node }
let us assume that the statement is true for tree with n-1 leaf nodes. Thus the tree has 2(n-1)-1 = 2n-3 nodes
to form a tree with n leaf nodes we need to add 2 child nodes to any of the leaf nodes in the above tree. Thus the total number of nodes = 2n-3+2 = 2n-1.
hence, proved
To prove: A strictly binary tree with n leaves contains 2n-1 nodes.
Show P(1): A strictly binary tree with 1 leaf contains 2(1)-1 = 1 node.
Show P(2): A strictly binary tree with 2 leaves contains 2(2)-1 = 3 nodes.
Show P(3): A strictly binary tree with 3 leaves contains 2(3)-1 = 5 nodes.
Assume P(K): A strictly binary tree with K leaves contains 2K-1 nodes.
Prove P(K+1): A strictly binary tree with K+1 leaves contains 2(K+1)-1 nodes.
2(K+1)-1 = 2K+2-1
= 2K+1
= 2K-1 +2*
* This result indicates that, for each leaf that is added, another node must be added to the father of the leaf , in order for it to continue to be a strictly binary tree. So, for every additional leaf, a total of two nodes must be added, as expected.
int N = 1000; insert here the value of N
int sum = 0; // the number of total nodes
int currFactor = 1;
for (int i = 0; i< log(N); ++i) //the is log(N) levels
{
sum += currFactor;
currFactor *= 2; //in each level the number of node is double than the upper level
}
if(sum == 2*N - 1)
{
cout<<"wow that the number of nodes is 2*N-1";
}

Resources