I wanted to print a binary tree by making a matrix based on coordinates which will corresponding nodes have in the tree. The binary tree is balanced and for every node goes that the nodes on the left are less than it and the nodes on the right are greater than it.
My tree is represented by a structure s(L,K,D), where L denotes the left branch N the node, and D the right branch. When it comes to an end the tree finishes with nil. For example, a simple tree with 1 as its first node and 2 and 3 its left and right node, will be represented as s(s(nil,2,nil),1,s(nil,3,nil)).
Binary tree example
In this example, node 7 will have coordinates (3,2). 2 because that is its depth in the binary tree (counting from 0), and 3 because of its index in the monotonically increasing list of nodes of the tree.( the list is [1,2,3,7...]).
Basically I can pack a tree in a matrix of dimensions NxM (N being the number of nodes, and M being the absolute depth of the tree[in this case 3]).
For this example the desired matrix would be:
Matrix example
, where I put ' ' character - where the blanks are, in order for the printing to be achieved in the desired way.
Is there any way to code a function which will generate this matrix?
Related
When constructing a segment tree, why it needs to be a full binary tree? I took some example input arrays and when made them to complete binary tree i am getting the same minimum in a range result. Then why make it a full binary tree when complete binary tree is also giving the same result.
Input array- 1, 3, 5, 7, 9, 11
The array representation of the segment tree for example array 1, 3, 5, 7, 9, 11 can be stored like (assuming the range query is finding the minimum element)
Sorry for a lazy diagram.
The number of tree nodes is calculated as pow*2-1 where pow = smallest power of 2 greater than or equal to n.
Clearly the above segment tree representation is a full binary tree and not a complete binary tree.
Can you share your segment tree array representation how are you storing it as a complete binary tree?
A segment tree is not a complete binary tree. For a binary tree to be complete, all levels except the last one need to be completely filled. Also, for the last level, nodes should be as left as possible.
Considering your input array with 6 elements, the tree will be as follows ( assuming 1-6 indices):-
Clearly, the last level has leaf nodes 1 and 2 followed by missing nodes that could have been children of node 3 (hypothetically) and then leaf nodes 4 and 5. This level has missing nodes with nodes 4 and 5 not as left as possible.
Whereas, every node has either 0 or 2 children making it a full binary tree.
What is the Formula to Find the minimum number of vertices required to make a binary tree (not a complete binary tree) of height 5 ?
A binary tree's height cannot be bigger than the number of nodes or vertices in the tree. So yes, the minimum number of vertices required for a binary tree of height 5 will be 5. Also, there must be n-1 edges between them. You can imagine a single series of connected nodes, and that is basically what you get.
Alternately, a full binary tree is a binary tree in which each internal vertex has exactly two children.This means a binary tree with n internal vertices has 2n + 1 vertices, 2n edges, and n + 1 leaves.
the minimum number of vertices in a binary tree of height n (with no further constraints) is always n.
proof:
if there were less than n nodes, the tree wouldn't be a valid binary tree (I guess I don't need to further explain this point)
if there were more than n nodes, it means at least one of the nodes has a brother (pigeonhole principle), which could be taken off the tree and it would result in a valid, smaller binary tree, so we know that this tree is not minimal, which opposes our assumption of a minimal tree.
-> a binary tree T is minimal -> T has n nodes
When trying to order a set of numbers into a binary search tree, is there always exactly one way to order them so the tree has the shortest height, in other words most efficient?
A set of numbers can be converted to a BST by taking one element as the root of the tree and arranging all other numbers around it. I could see the following situation contradicting this theory:
Picking one root leads to a tree of height h, with the left subtree being 'taller' than the right subtree.
Picking another root leads to a different tree, also of height h, with the right subtree being 'taller' than the left subtree.
Another simple example involves swapping the order of insertion of two consecutive elements that are not directly related, and thus do not affect each other's position in the tree.
Disproof by counter-example.
Let the set S = {0, 1, 2, 3}.
Insert the elements into a binary search tree in the following order: 1, 0, 2, 3
1
/ \
0 2
\
3
Insert the elements into a binary search tree in the following order: 1, 2, 0, 3
1
/ \
0 2
\
3
Because these two trees have different orders of insertion, and yet both have minimum height, the statement that there is only one order of insertion that provides a binary search tree of minimum height is false.
If the actual ordering of elements on the tree is what you're concerned about, insert the elements of the set in the following order: 2, 1, 0, 3
2
/ \
1 3
/
0
Again, this tree has the same height as the previous trees, thus showing that a different ordering of items in the tree can also produce a tree of minimum height.
(An aside)
You can always build a minimum height tree by first sorting the elements of the set, then continually subdividing the sorted set to ensure balance and complete filling of each row.
Take the median element of the set. In the case of an even number of elements, take the larger of the two 'middle' elements. This will become the root of the tree.
Take all the elements below the median. This will become the left subtree of the root.
Take all the elements above the median. This will become the right subtree of the root.
Recursively create the left and right subtrees from these sets.
This should ensure that you have a complete binary tree, which will always be of minimum height.
For exa, this is the tree.
10
12 -1
5 1 1 -2
2 3 10 -9
How to find the node with maximum value?
Given the problem as stated, you need to traverse the entire tree. See proof below.
Traversing the entire tree should be a fairly trivial process.
Proof that we need to traverse the entire tree:
Assume we're able to identify which side of a tree the maximum is on without traversing the entire tree.
Given any tree with the maximum node on the left. Call this maximum x.
Pick one of the leaf nodes on the right. Add 2 children to it: x+1 and -x-1.
Since x+1-x-1 = 0, adding these won't change the sum at the leaf we added it to, thus nor the sums at any other nodes in the tree.
Since this can be added to any leaf in the tree, and it doesn't affect the sums, we'd need to traverse the entire tree to find out if this occurs anywhere.
Thus our assumption that we can identify which side of a tree the maximum is on without traversing the entire tree is incorrect.
Thus we need to traverse the entire tree.
In the general case, you need to traverse the entire tree. If the values in the tree are not constrained (e.g. all non-negative, but in your example there are negative values), then the value in a node tells you nothing about the individual values below it.
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.