Suppose we have a node's left child in a binary tree.
Can the right child of the previously mentioned left child have a greater key-value than his parent's parent?
Well, you can put any value you want in any node of the tree. It's a free country.
Now, if you want it to be a usable Binary Search Tree, then, No. Every node in the left subtree must be less than the parent, (and every node in the right subtree must be greater than it). It won't matter if it's the child's left or right child. They are all on the left side of the grandparent, so they must be less.
Related
In these slides (13) the deletion of a point in a kd-tree is described: It states that the left subtree can be swapped to be the right subtree, if the deleted node has only a left subtree. Then the minimum can be found and recursively be deleted (just as with a right subtree).
This is because kd-trees with equal keys for the current dimensions should be on the right.
My question: Why does the equal key point have to be the right children of the parent point? Also, what happens if my kd-tree algorithm returns a tree with an equal key point on the left?
For example:
Assume the dataset (7,2), (7,4), (9,6)
The resulting kd-tree would be (sorted with respect to one axis):
(7,2)
/ \
(7,4) (9,6)
Another source that states the same theory is this one (paragraph above Example 15.4.3)
Note that we can replace the node to be deleted with the least-valued node from the right subtree only if the right subtree exists. If it does not, then a suitable replacement must be found in the left subtree. Unfortunately, it is not satisfactory to replace N's record with the record having the greatest value for the discriminator in the left subtree, because this new value might be duplicated. If so, then we would have equal values for the discriminator in N's left subtree, which violates the ordering rules for the kd tree. Fortunately, there is a simple solution to the problem. We first move the left subtree of node N to become the right subtree (i.e., we simply swap the values of N's left and right child pointers). At this point, we proceed with the normal deletion process, replacing the record of N to be deleted with the record containing the least value of the discriminator from what is now N's right subtree.
Both refer to nodes that only have a left subtree but why would this be any different?
Thanks!
There is no hard and fast rule to have equal keys on right only. You can update that to left as well.
But doing this, you would also need update your algorithms of search and delete operations.
Have a look at these links:
https://www.geeksforgeeks.org/k-dimensional-tree/
https://www.geeksforgeeks.org/k-dimensional-tree-set-3-delete/
In the case of Binary Search Trees why cannot we simply put the predecessor in place of the successor of a node in deletion case where a node is having two children?
We'd like to delete such a node with minimum amount of work and disruption to the structure of the tree.
Suppose we want to delete the node containing 6 from the following tree:
The standard solution is based on this idea: we leave the node containing 6 exactly where it is, but we get rid of the value 6 and find another value to store in the 6 node. This value is taken from a node below the 6s node, and it is that node that is actually removed from the tree.
Now, what value can we move into the vacated node and have a binary search tree? Well, here's how to figure it out. If we choose value X, then:
everything in the left subtree must be smaller than X.
everything in the right subtree must be bigger than X.
Let's suppose we're going to get X from the left subtree. (2) is guaranteed because everything in the left subtree is smaller than everything in the right subtree. What about (1)? If X is coming from the left subtree, (1) says that there is a unique choice for X - we must choose X to be the largest value in the left subtree. In our example, 3 is the largest value in the left subtree. So if we put 3 in the vacated node and delete it from its current position we will have a BST with 6 deleted.
The result is :
why cannot we simply put the predecessor in place of the successor of a node in deletion
case where a node is having two children?
We can put both and it is not necessary to replace the deleted node with the inorder successor. This is because in either case, the general contract of a BST is maintained.
Case1. Replace the deleted node with the inorder successor.
This is done by finding the leftmost node in the deleted node's right subtree.
Case2. Replace the deleted node with the inorder predecessor.
This is done by finding the rightmost node in the deleted node's left subtree.
Note that both these cases will keep all the elements in the left subtree smaller and all elements in right subtree greater than the element that we have brought into the position of the deleted node.
Given a binary tree I need to implement a method findAllElements(k) to find all the elements in the tree with a key equal to k.
The idea I had is the first time you come across an element with key k. All the elements with the same key should be either in the left child's right subtree or the right child's left subtree. But I was told this may not be the case?
I just need to find a way to implement an algorithm. So pseudo code is needed.
I probably should have added this sorry. But the implementation is that the left subtree contains keys less than or equal to the key at the root and the right subtree contains keys greater than or equal to the key at the root.
It depends on your tree implementation, by binary tree I assume you mean binary search tree, and you use operator< to compare the key. That is, The left subtree of a node contains only nodes with keys less(<) than the node's key, and the right subtree of a node contains only nodes with keys not less(!<) than the node's key.
e.g.
7
/ \
4 7
/ \
6 8
If there is multi equal keys in the tree, do this
k < current_node_key, search left subtree
k > current_node_key, search right subtree
k == current_node_key, record current node , then search right tree
Look at the current node. If its key is higher than k, search the left subtree. If it is lower, search the right subtree. If it is equal, search both left and right subtrees (and also include the current node in the results).
Do that recursively starting from the root node.
Thought I'd come back and explain what the result should have been after conversing with me teacher. So if you perform a method findElement(k) that will find an element with the key equal to k, the element it find should be the element highest in the tree with key k (let's denote this element V).
Then from this element V, other elements the contain a key=k will either be in the left child subtree (particularly all the way to the right) or the right child subtree (particularly all the way to the left). So for the left child keep going to the next nodes right child until an element with key=k is found...now... every element in the subtree with this node as its root must have a key=k (this is the part i didn't recognize at first) thus ANY kind of traversal of this full subtree can be done to find and store all the elements in this subtree (visiting every node in it). This type of thing must be repeated for the right child but visiting every left child until an element with a key=k is found. then the subtree with this element as its root has all the other elements with key=k in it and they can be found by one again fully traversing this subtree.
That is just a word description of it obviously, sorry for the length, and any confusion. Hopefully this will help anyone else trying to solve a similar problem.
Does such a tree exist and have a name, or is it just a figment of my imagination? I used to think heaps have this property but it just seems that the only requirement is for the children to be less than the parent.
It's exactly the opposite, but you may be thinking of a binary search tree, which has the following properties:
The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.
There must be no duplicate nodes.
So every left node is guaranteed to be less than every right node. You can find the max by going right from the root node until you can't go right any more.
I am trying to understand why when deleting a node in a BST tree and having to keep the children and adhering to the BST structure, you have to either take the node's right child (higher value, then node being deleted) and if that right child has a left child take that child. Else just the the node being deleted right child.
Why don't you just take the node being deleted left child, if there's one. It still works out correctly?
Or have I missed something.
I'm reading this article.
You're oversimplifying.
The node selected to replace the one that was deleted must be larger than all the nodes to the left of the deleted one, and smaller than all the nodes to the right. So it must be either the left subtree's rightmost descendant or the right subtree's leftmost descendant; except if one or the other subtree is entirely absent, we can remove a level of tree entirely simply by replacing the deleted node with the child that was present.
The rules listed in the article will always give you the right subtree's leftmost descendant when both trees are present. If you wished, you could indeed derive an alternative ruleset that used the leftmost subtree's rightmost descendant instead.
It does not "work out correctly" to just always use the left child. Indeed, if there is a child on the right and the left child itself has two children, it cannot even be done without essentially rebuilding the tree.
You would be correct for the special case that you described. But for something more general where you can have many more levels deeper than the node being deleted you need to replace that node with a node that will be less than everything to the right, and greater than everything to the left. So as an example:
2
/ \
1 6
/ \
4 7
\
5
Let's say you wanted to move the node 6, now following your instructions we will replace it with the left child, node 4. Now what do we do with node 5? We could make it the left child of node 7 (or the left most descendant of node 7 if it existed), but why would you do all this reshuffling when you know that removing a leaf is trivial and you just want to replace the node with another node that would keep every node on the left less and every node on the right greater.