Given number of nodes N (ie a preorder seq of length N) in a balanced binary tree,I am trying to find the number b of possible balanced binary trees that can be formed.
I noticed it is possible that there might be variations in the leaves as well as the higher-level nodes:
A
/ \
B C
/ / \
D E F
/
G
The constraint is generally applied recursively to every subtree. That is, the tree is only balanced if:
1.The left and right subtrees' heights differ by at most one, AND
2.The left subtree is balanced, AND
3.The right subtree is balanced
Related
I want to write a method to find whether a tree has at least a pair of identical subtrees, the subtrees have to be identical in both value and structure.
Suppose you are given a tree as follows:
a
/ \
b f
/ / \
c g d
/ / /
d h e
/
e
This would return true because we have a pair of identical trees with root d.
My thought is to traverse each node and build a map of node name mapped to list of tree nodes. In each iteration, we check if current node name is in the map or not. If it's in, then we can call boolean isSameTree(TreeNode t1, TreeNode t2) function with current node against every node in the list of tree nodes to see if they are identical.
The time complexity would be O(n^3). And I wonder if we can do better than that!
Your example tree also has a pair of identical trees with root e. In general, if two trees are identical then either they are both leaves or they have subtrees which are identical. So you can simplify your test to checking whether all of the leaves in the original tree are distinct, which takes O(n) hashing operations and average case Theta(n) equality comparisons unless the hash is very poor.
I am reading The Algorithm Design Manual. The author states that the height of a tree is:
h = log n,
where
h is height
n = number of leaf nodes
log is log to base d, where d is the maximum number of children allowed per node.
He then goes on to say that the height of a perfectly balanced binary search tree, would be:
h = log n
I wonder if n in this second statement denotes 'total number of leaf nodes' or 'total number of nodes'.
Which brings up a bigger question, is there a mathematical relationship between total number of nodes and the height of a perfectly balanced binary search tree?
sure, n = 2^h where h, n denote height of the tree and the number of its nodes, respectively.
proof sketch:
a perfectly balanced binary tree has
an actual branching factor of 2 at each inner node.
equal root path lengths for each leaf node.
about the leaf nodes in a perfectly balanced binary tree:
as the number of leafs is the number of nodes minus the number of nodes in a perfectly balanced binary tree with a height decremented by one, the number of leafs is half the number of all nodes (to be precise, half of n+1).
so h just varies by 1, which usually doesn't make any real difference in complexity considerations. that claim can be illustrated by remembering that it amounts to the same variations as defining the height of a single node tree as either 0 (standard) or 1 (unusual, but maybe handy in distinguishing it from an empty tree).
It doesn't really matter if you talk of all nodes or just leaf nodes: either is bound by above and below by the other multiplied by a constant factor. In a perfectly balanced binary tree the number of nodes on a full level is the number of all nodes in levels above plus one.
In a complete binary tree number of nodes (n) and height of tree (h) have a relationship like this in below.
n = 2^(h+1) -1
this is the all the nodes of the tree
Given a set of values, it's possible for there to be many different possible binary search trees that can be formed from those values. For example, for the values 1, 2, and 3, there are five BSTs we can make from those values:
1 1 2 3 3
\ \ / \ / /
2 3 1 3 1 2
\ / \ /
3 2 2 1
Many data structures that are based on balanced binary search trees use tree rotations as a primitive for reshaping a BST without breaking the required binary search tree invariants. Tree rotations can be used to pull a node up above its parent, as shown here:
rotate
u right v
/ \ -----> / \
v C A u
/ \ <----- / \
A B rotate B C
left
Given a BST containing a set of values, is it always possible to convert that BST into any arbitrary other BST for the same set of values? For example, could we convert between any of the five BSTs above into any of the other BSTs just by using tree rotations?
The answer to your question depends on whether you are allowed to have equal values in the BST that can appear different from one another. For example, if your BST stores key/value pairs, then it is not always possible to turn one BST for those key/value pairs into a different BST for the same key/value pairs.
The reason for this is that the inorder traversal of the nodes in a BST remains the same regardless of how many tree rotations are performed. As a result, it's not possible to convert from one BST to another if the inorder traversal of the nodes would come out differently. As a very simple case, suppose you have a BST holding two copies of the number 1, each of which is annotated with a different value (say, A or B). In that case, there is no way to turn these two trees into one another using tree rotations:
1:a 1:b
\ \
1:b 1:a
You can check this by brute-forcing the (very small!) set of possible trees you can make with the rotations. However, it suffices to note that an inorder traversal of the first tree gives 1:a, 1:b and an inorder traversal of the second tree gives 1:b, 1:a. Consequently, no number of rotations will suffice to convert between the trees.
On the other hand, if all the values are different, then it is always possible to convert between two BSTs by applying the right number of tree rotations. I'll prove this using an inductive argument on the number of nodes.
As a simple base case, if there are no nodes in the tree, there is only one possible BST holding those nodes: the empty tree. Therefore, it's always possible to convert between two trees with zero nodes in them, since the start and end tree must always be the same.
For the inductive step, let's assume that for any two BSTs of 0, 1, 2, .., n nodes with the same values, that it's always possible to convert from one BST to another using rotations. We'll prove that given any two BSTs made from the same n + 1 values, it's always possible to convert the first tree to the second.
To do this, we'll start off by making a key observation. Given any node in a BST, it is always possible to apply tree rotations to pull that node up to the root of the tree. To do this, we can apply this algorithm:
while (target node is not the root) {
if (node is a left child) {
apply a right rotation to the node and its parent;
} else {
apply a left rotation to the node and its parent;
}
}
The reason that this works is that every time a node is rotated with its parent, its height increases by one. As a result, after applying sufficiently many rotations of the above forms, we can get the root up to the top of the tree.
This now gives us a very straightforward recursive algorithm we can use to reshape any one BST into another BST using rotations. The idea is as follows. First, look at the root node of the second tree. Find that node in the first tree (this is pretty easy, since it's a BST!), then use the above algorithm to pull it up to the root of the tree. At this point, we have turned the first tree into a tree with the following properties:
The first tree's root node is the root node of the second tree.
The first tree's right subtree contains the same nodes as the second tree's right subtree, but possibly with a different shape.
The first tree's left subtree contains the same nodes as the second tree's left subtree, but possibly with a different shape.
Consequently, we could then recursively apply this same algorithm to make the left subtree have the same shape as the left subtree of the second tree and to make the right subtree have the same shape as the right subtree of the second tree. Since these left and right subtrees must have strictly no more than n nodes each, by our inductive hypothesis we know that it's always possible to do this, and so the algorithm will work as intended.
To summarize, the algorithm works as follows:
If the two trees are empty, we are done.
Find the root node of the second tree in the first tree.
Apply rotations to bring that node up to the root.
Recursively reshape the left subtree of the first tree to have the same shape as the left subtree of the second tree.
Recursively reshape the right subtree of the first tree to have the same shape as the right subtree of the second tree.
To analyze the runtime of this algorithm, note that applying steps 1 - 3 requires at most O(h) steps, where h is the height of the first tree. Every node will be brought up to the root of some subtree exactly once, so we do this a total of O(n) times. Since the height of an n-node tree is never greater than O(n), this means that the algorithm takes at most O(n2) time to complete. It's possible that it will do a lot better (for example, if the two trees already have the same shape, then this runs in time O(n)), but this gives a nice worst-case bound.
Hope this helps!
For binary search trees this can actually be done in O(n).
Any tree can be "straightened out", ie put into a form in which all nodes are either the root or a left child.
This form is unique (reading down from root gives the ordering of the elements)
A tree is straightened out as follows:
For any right child, perform a left rotation about itself. This decreases the number of right children by 1, so the tree is straightened out in O(n) rotations.
If A can be straightened out into S in O(n) rotations, and B into S in O(n) rotations, then since rotations are reversible one can turn A -> S -> B in O(n) rotations.
I know that from a general tree you can construct a unique binary tree, but is the reverse true? i.e can you get a unique general tree from a binary tree?
Yes. The following transformation is reversible:
Given a general tree with ordered but not indexed children,
encode the first child as the left child of its parent, and each other node as a right child of its (former) sibling.
The reverse is:
Given a binary tree with distinguished left and right children, read the left child of a node as its first child and the right child as its next sibling.
So, the following tree
a
/|\
b c d
is encoded as
a
/
b
\
c
\
d
while the following tree
a
/ \
b c
|
d
is encoded as
a
/
b
/ \
d c
(read: d is the first child of b, c is the sibling of a).
Note that you can encode any rooted forest (with ordered components, otherwise the representation is not unique) by assigning a sibling to the root, so this
a
/ \
b c
\ \
d e
would be read as
a c e
/ \
b d
here is another method to get a unique general (undirected) tree from a binary tree:
a vertex binary tree may have 0...3 graph neighbors.
append 12 nodes to the root
append 8 nodes to each left child
append 4 nodes to each right child
this operation is reversible:
label the node with at least 12 neighbors "root". If not unique, fail.
label each node with 8..11 neighbors "left".
label each node with 4..7 neighbors "right".
remove all leaves
orient all edges away from the root
if any node has more than one left child or more than one right child, fail.
So,
There is a bijection between ordered rooted trees and binary trees (first and second algorithm).
Since any general tree can be arbitrarily rooted, there is a injection from general (directed or undirected) trees to binary trees.
There is an injection from binary trees to general undirected trees (third algorithm)
Since there is an injection from binary trees to general trees and back, there must exist a bijection between general (directed or undirected) trees and binary trees.
I feel unlikely. Usually, binary tree distinguishes left child and right child. However, general trees don't.
How are we supposed to get a unique general tree from these two binary tree.
X X
/ \ / \
Y Z Z Y
And how about these two?
X X
/ \
Y Y
On the other hand,
If you choose to not distinguish left or right child of a binary tree, or choose to respect the sequence children appears in a general tree, just map each binary tree to itself. That will be a unique general tree for each binary tree.
I am searching for a proof that all AVL trees can be colored like a red-black tree?
Can anyone give the proof?
By definition R/B trees can be slightly less balanced then AVL-s, as |maxPath - minPath| must be <= 1 for AVLs and maxPath <= 2 * minPath for R/Bs so that not every R/B is an AVL but on the other hand there is no need for the AVL-s To have Empty subTrees so
4
/ \
3 6
/\ /\
1 E 5 8
is a perfectly legal AVL and it is not an R/B because R/B cannot contain Leaves and must be terminated by Empty trees which are coloured always Black - so that you cannot colour the tree above.
To make it R/B you are allowed to convert every leaf x into node E x E
and then follow these rules:
R/B Tree:
Must be a BST
must contain only nodes and empty trees which are coloured either Black or Red
Every Red node has black children
All Empty Trees are Black
Given a node, all paths to Empty Trees must have same number of Black Nodes
Any Leaf can be replaced with Node whose Left & Right subTrees are Empty
Max Path T ≤ 2 * Min Path T
Btw just realized it coloured my nodes and leaves in Red - this was not intended.
Karol
The red-black tree adjusts the branch heights by red nodes, so if the height difference is bounded, you can always adjust all the branches, starting from the shortest black branch. But it requires a very large cost, because you have to count all the branch heights.
The maximum local height difffernce bound of red-black tree is 2.
I suspect the answer is no.
AVL trees balance better than RB trees, which means they balance differently, which would rather imply that you could not colour every AVL tree as a valid RB tree.
The answer is yes, every AVL tree can be colored Red-Black, and the converse doesn't hold.
I haven'y exactly figured out HOW to do it tho, and am also seeking the proof.