I'm trying to implement an avl tree. I have a height field in each node which represents the max distance to null. When I delete a node, I replace it with its successor. But I have a problem determining what the height of of the new node will be (in place of the deleted node). How can I determine its height?
Related
In question it is given we can use depth only and not height.
(As we know for height we can say if difference between height of left subtree and height of right subtree is is at most one then it will be balanced)
Using depth can we find a way to prove tree balanced or not?
I tried by finding relation between different depth trees
What I got is that
If depth max = n
Then there must be n nodes whose depth is n-1
But this is just one condition I got.
It is not sufficient condition
( You can ignore my approach and try other thing .As there is no condition on approaching the problem)
The principle is the same as with height: use the following logic:
For each node do:
Get the maximum among the depths of all the nodes in the left subtree. Default (when no left subtree is present) is the current node's depth.
Get the maximum among the depths of all the nodes in the right subtree. Default (when no right subtree is present) is the current node's depth.
The difference between these two should not be more than 1.
If you implement this with a post-order traversal through the tree, you can keep track of the maximum depths -- needed in the first two steps -- as you traverse the tree.
Are height and maximum height different metrics for binary trees?
For the tree above, is the height 2 and maximum height 2+1 = 3?
Height of a binary tree is the longest path from root to any leaf nodes.
So, height and maximum height has no difference.
The height (or maximal depth) of your tree is, as you say, 2 because that is the largest depth of any node.
The maximum height is a less well-defined term, so unless you specify how you choose to define it, I will interpret literally, meaning the maximum height that a binary tree of this size can have. Since a binary tree requires that a node have at most two children, we find that we can just assign each node one single child and connect them all under each other in a long chain. This is essentially a one-dimensional linked list. Since your tree has 5 nodes, the height of such a tree would be 5-1 (because we don't count the root node in the definition you are using). So the maximum height, if interpreted this way, would be 4. But if you are using a different definition for maximum height, you will have to specify it.
According to definition, height of a binary tree is Maximum of height of left sub-tree of the root node and height of right sub-tree of root node +1.
MAX(left sub-tree of root height, right sub-tree of root height) + 1.
And this is also the maximum height of the binary tree.
Now, what you are confused about is the Diameter of binary tree.
Diameter is the length of the longest path between any two nodes of the tree. In your example, height of binary tree is 2 whereas diameter of binary tree is 3.
In the standard process of AVL tree insertion, after we insert a new node, we will do adjustment from bottom to top, and during the process, is it possible a sub-tree height increase by one (because of insertion and rotation operation), while the sub-tree (after height increase by one), still have the same height of left/right child? If so, an example is appreciated, and if not, it will be great if anyone could explain why. Thanks. :)
Here is a reference to AVL tree (https://en.wikipedia.org/wiki/AVL_tree)
regards,
Lin
From Wikipedia Binary Tree page:
A balanced binary tree has the minimum possible maximum height (a.k.a.
depth) for the leaf nodes, because for any given number of leaf nodes
the leaf nodes are placed at the greatest height possible.
One common balanced tree structure is a binary tree structure in which
the left and right subtrees of every node differ in height by no more
than 1
For example:
This is a balanced tree.
And if we insert 1 it's height increases by 1. Yet it is a balanced tree again. Because left and right subtrees differ in height no more than 1.
BTW, AVL tree is a self-balancing binary search tree. So it is not possible to lose balance after insertion. Because after every insertion, tree balances itself by making necessary rotations.
I think you use the term balanced wrongly. You consider balanced as no height difference, but it's at most 1 height difference in definition.
Your question:
In the standard process of AVL tree insertion, is it possible a sub-tree height increase by one (because of insertion and rotation operation), while the sub-tree (after height increase by one), still have the same height of left/right child?
If we would have a tree which has the same height from left and right branches, and if we would insert a node into a leaf node on left branch, height would increase, because height of the tree is maximum(height(left_branch, right_branch)). Because after this operation height(left_branch) equals to height(right_branch)+1. So, they can't be equal.
In short, your precondition is height(left_branch) == height(right_branch)
Your operation is increasing height of left_branch by 1
So height(left_branch) == height(right_branch) condition can't be true anymore.
It is not possible after the insertion to have the left and right child of the sub-tree to remain same with a change in height.
Lets consider a simple example with only <3 nodes in a sub-tree. The possiblities of balance factor are,
+1 - which is Root node in subtree with 1 Left Child and no Right child
-1 - which is Root node in subtree with 1 Right Child and no Left child
0 - Root node in subtree has 1 node in Right and Left.
For SubTree with Balance factor +1,
if we insert into the Right, we are ok
if we insert into the Left, the balance factor changes to 2. So we need to balance the tree in which case the the height of the subtree is changed.
For SubTree with Balance factor -1,
if we insert into the Left we are ok
if we insert into the Right, the balance factor changes to -2. So we need to balance the tree in which case the the height of the subtree is changed.
For SubTree with Balance factor 0,
if we insert into the Left, we are ok. Height is changed for but the child node is changed as well.
if we insert into the Right, we are ok. Height is changed for but the child node is changed as well.
So, it is not possible to have the height changed and still have same right and left child heights.
I am looking at the code of inserting into an augmented Red black tree. This tree has an additional field called "size" and it keeps the size of a subtree rooted at a node x. Here is the pseudocode for inserting a new node:
AugmentedRBT_Insert(T,x){
BST_Insert(T,x); //insert as if it is a normal BST
x[color]=red; //insert as a red node
size[x]=1;
tmp=parent[x];
while(tmp!=NULL){ //start from the node x and follow the path to root
size[tmp]=size[tmp]+1; //update the size of each node
tmp=parent[tmp];
}
}
Forget about fixing the coloring and rotations, they will be done in another function. My question is, why do we set the size of the newly added node "x" to 1? I understand that it will not have any subtrees, so its size must be 1, but one of the requirements of RBT is that every red node has two black children, in fact every leaf node is NULL and even if we insert the node "x" as black, it still should have 2 black NULL nodes and i think we must set its size to 3? Am i wrong?
Thanks.
An insertion in a red-black tree, as in most binary trees, happens directly at a leaf. Hence the size of the subtree rooted at the leaf is 1. The red node does have two black children, because leaves always have the "root" or "nil" as a child, which is black. Those null elements aren't nodes, so we wouldn't count them.
Then, we go and adjust the sizes of all parents up to the root (they each get +1 for the node we just added).
Finally, we fix these values when we rotate the tree to balance it, if necessary. In your implementation, you will probably want to do both the size updates and rotations in one pass instead of two.
Problem: I have a binary tree, all leaves are numbered (from left to right, starting from 0) and no connection exists between them.
I want an algorithm that, given two indices (of 2 distinct leaves), visits the tree starting from the greater leaf (the one with the higher index) and gets to the lower one.
The internal nodes of the tree do not contain any useful information.
I should chose the path based only on the leaves indices. The path start from a leaf and terminates on a leaf, and of course I can access a leaf if I know its index (through an array of pointers)
The tree is static, no insertion or deletion of nodes is allowed.
I have developed an algorithm to do it but it really sucks... any ideas?
One option would be to find the least common ancestor of the two nodes, along with the sequence of nodes you should take from each node to get to that ancestor. Here's a sketch of the algorithm:
Starting from each node, walk back up to that node's parent until you reach the root. Count the number of nodes on the path from each node to the root. Let the height of the first node be h1 and the height of the second node be h2.
Let h = min(h1, h2). This is the height of the higher of the two nodes.
Starting from each node, keep following the node's parent pointer until both nodes are at height h. Record the nodes you followed during this step. At this point, both nodes are at the same height.
Until you find a common node, keep marching upwards from each node to its parent. Eventually you will hit their common ancestor. At this point, follow the path from the first node up to this ancestor, then down the path from the ancestor down to the second node.
In the worst case, this takes O(h) time and O(h) space, where h is the height of the tree. For a balanced binary tree is this O(lg n) time and space, which is quite good.
If you're interested in a Much More Hardcore version of this algorithm, consider looking into Tarjan's Least Common Ancestors algorithm, which with linear preprocessing time, can be used to find the least common ancestor much more rapidly than this.
Hope this helps!
Distance between any two nodes can be calculated with the help of lowest common ancestor:
Dist(n1, n2) = Dist(root, n1) + Dist(root, n2) - 2*Dist(root, lca)
where lca is lowest common ancestor.
see this for more help about this algorithm and see this video for learning how to calculate lca.