How can I remove all isRemoved=true; data in Binary Search Tree in one method?
Or two it doesn't matter.
There is a remove method already and it marks the node that is coming from method isRemoved=true.
So,constructor has four specilization they are Type data,left,right,isRemoved.
The method can work recursively or not doesn't matter.
My idea is traversing all of the nodes when I found the removed go and delete method and delete it then turn back and keep going look at the nodes. I couldn't implement the idea because BST is complicated. Can you guys give me some clue?
First you will need to decide how you are going to traverse your tree (inorder, preorder, postorder).
Then you will handle three separate cases for a node to be deleted; when the node is a leaf, when the node has one child, and when there are both a left and a right child.
If the node is a leaf, you can remove it.
If the node has a child, you can set the node's child to be the parent node's child, then remove the node.
If the node has two children, you can go to the subtree of the left child and replace the node with the rightmost child of the left subtree. Since the rightmost node in the subtree is a leaf, you can replace without rebalancing the tree.
Traverse the tree while removing the isRemoved=true nodes using one of the methods above until you reach the last node in the traversal.
Related
I tried writing an insert code in Java for Btree but cant split the nodes correctly, can anybody direct me to a good algorithm for insert,split and nonfullInset in Btrees?
thanks
Assuming per node:
maximum number of children for is D,
maximum number of keys is K= D-1,
minimum number of children is d = D/2,
minimum number of keys is k= D/2-1
here are the algorithms:
Insert: Search the tree to find the leaf node for containing the key. Insert the key. See if the key is over flown (the number of keys is higher than D-1), if not operation is complete. If over flown, Split the node into 2 nodes (itself and a new one), move the last (k) keys to the new node, leaving the node (leaf node) with k +1 keys. Move the last key in leaf node to parent. If parent is over flown repeat these steps.
Delete: Search the tree to find the node containing the key you want to remove. 2 cases are possible. The container node is a leaf node or it is an internal non-leaf node. If it is an internal node, first find the immediate predecessor of the key in the node , which always comes from a lead node. Then replace the key with this predecessor key. Now you need to delete the key from a leaf node. (notice that the deletion from an internal node is always reduced to deletion from a leaf node). If a leaf node, remove the key from the leaf node. Check if the leaf node is under flown (has less than k keys), if not operation is complete. If under flown, however 3 cases are possible. If the node has a left sibling that has at least k+1 keys, then perform a right rotation via parent. Else if the node has a right sibling that has at least k+1 keys, then perform a left rotation via parent. Else if the node does not have any sibling with at least k+1 keys, then join the node with one of its sibling, while bringing down a key from parent. Then check if parent is under flown, if under flown repeat these steps to fix the parent.
Search: is similar to binary search tree, the main difference is that now you need to also perform a search with in each node, since each node has sorted keys, you can perform a binary search over each node.
I've implemented a binary search tree with nodes (represented as users) but I'm having trouble getting my deFriend() method to work. This method should delete a node from the tree whilst keeping the "rules" of a binary search tree - e.g. root bigger than left sub-tree, but smaller than right sub-tree.
I understand that when deleting a node from a binary search tree, I should consider 3 cases:
1 - when the node to delete has no children,
2 - when the node to delete has one child,
3 - when the node to delete has two children. can't figure this one out
My deFriend() method works for the first two cases but not for the last one. I even know what node I need to replace it with if it's the third case but I can't get it down with code. I can conceptualize it or draw it on paper, but I can't translate that to code. I've included links to the two classes that I think are necessary to fixing my problem. I'm convinced my problem lies between lines 111 and 114 of my BinaryTree class. Thanks in advance.
User class: https://gist.github.com/anonymous/732f02628f6edf622d88363b68cf22ee
BinaryTree class: https://gist.github.com/anonymous/1be7b5577c959dc1bcf6c77474b11bce
When removing a node from a binary search tree it is mandatory to maintain the in-order sequence of the nodes. There are three possible cases to consider:
if node has no children simply remove the node from the tree.
if node has one child remove the node and replace it with its child.
if node D has two children do not delete it. Instead, choose either its in-order predecessor node or its in-order successor node as replacement node E. Copy the user values of E to D. If E does not have a child simply remove E from its previous parent. If E has a child, say F, it is a right child. Replace E with F at E's parent.
I was just wondering, given a node which points to its left and right children, is it possible to somehow get an inorder print of the whole bst tree?
All i know about the tree is that it is BST.
And all I know about the node is that he knows who his children are (left and right).
I don't have access to neither the root nor the father of the node.
The node chosen is picked randomly, and I need to return an inorder of the whole tree.
I think there is not enough info to get started at, and my friend got this question during a job interview, and was wondering if that was an unsolvable question or is there a trick I don't know about?
Thanks in advance for any help :)
The only thing you can do from this situation is to travel downwards, because you have no pointer to the parent node. The only case when you can print the whole tree is when the node considered is the root.
So, you can get the inorder print of the subtree rooted at the current node. If this node is the root, then it prints the whole tree. If it is not, then it does not.
Just in case, inorder print is simple:
def inorder(node):
if node == null: return
inorder(node.left)
print node.data
inorder(node.right)
Assume the height of the BST is h.
If we want to delete a node with two children, then what would be the time complexity of the process.
I know that in a normal binary tree, the time complexity for deletion is O(h); O(n) worst case and O(logn) best case. But since we are replacing the key of the deleting node by the minimum node of right sub tree of it, it will take more time to find the minimum key.
So does anybody know how to explain the time complexity in this situation?
Source Wikipedia :
Deletion
There are three possible cases to consider:
Deleting a leaf (node with no children): Deleting a leaf is easy, as we can simply remove it from the tree.
Deleting a node with one child: Remove the node and replace it with its child.
Deleting a node with two children: Call the node to be deleted N. Do not delete N. Instead, choose either its in-order successor node or its in-order predecessor node, R. Copy the value of R to N, then recursively call delete on R until reaching one of the first two cases. If you choose in-order successor of a node, as right sub tree is not NIL( Our present case is node has 2 children), then its in-order successor is node with least value in its right sub tree, which will have at a maximum of 1 sub tree, so deleting it would fall in one of first 2 cases.
Deleting a node with two children from a binary search tree. First the rightmost node in the left subtree, the inorder predecessor 6, is identified. Its value is copied into the node being deleted. The inorder predecessor can then be easily deleted because it has at most one child. The same method works symmetrically using the inorder successor labelled 9.
Consistently using the in-order successor or the in-order predecessor for every instance of the two-child case can lead to an unbalanced tree, so some implementations select one or the other at different times.
Runtime analysis:
Although this operation does not always traverse the tree down to a leaf, this is always a possibility; thus in the worst case it requires time proportional to the height of the tree. It does not require more even when the node has two children, since it still follows a single path and does not visit any node twice. Hence the pointer adjustments in all three cases need constant time.
Useful Links :
http://en.wikipedia.org/wiki/Binary_search_tree#Deletion
http://cse.iitkgp.ac.in/~pb/algo-1-pb-10.pdf
I have to solve the following constructor for a BinaryTree class in java:
BinaryTree(GeneralTree<T> aTree)
This method should create a BinaryTree (bt) from a General Tree (gt) as follows:
Every Vertex from gt will be represented as a leaf in bt.
If gt is a leaf, then bt will be a leaf with the same value as gt
If gt is not a leaf, then bt will be constructed as an empty root, a left subTree (lt) and a right subTree (lr). Lt is a stric binary tree created from the oldest subtree of gt (the left-most subtree) and lr is a stric binary tree created from gt without its left-most subtree.
The frist part is trivial enough, but the second one is giving me some trouble. I've gotten this far:
public BinaryTree(GeneralTree<T> aTree){
if (aTree.isLeaf()){
root= new BinaryNode<T>(aTree.getRootData());
}else{
root= new BinaryNode<T>(null); // empty root
LinkedList<GeneralTree<T>> childs = aTree.getChilds(); // Childs of the GT are implemented as a LinkedList of SubTrees
child.begin(); //start iteration trough list
BinaryTree<T> lt = new BinaryTree<T>(childs.element(0)); // first element = left-most child
this.addLeftChild(lt);
aTree.DeleteChild(hijos.elemento(0));
BinaryTree<T> lr = new BinaryTree<T>(aTree);
this.addRightChild(lr);
}
}
Is this the right way? If not, can you think of a better way to solve this? This solution, for example, gives me a bunch of nodes with no data at all, I don't know if this is an issue of the problem itself or mine.
Thank you!
The problem is that most trees cannot be validly reduced to a binary tree.
Reading your comment you are fully aware of that.
Taking for example a tree with a root node with 3 children. There is no direct way to make a binary tree out of this without sacrificing connectivity. That's where those empty nodes come from. With them, the structure of the general tree is preserved. You can reconstruct it, deleting the empty nodes and reassembling the tree from the two subtrees.
I have not debugged your code. If it does what you said it would do, it is a good solution. Empty nodes sort of store the connectivity information of the general tree. They are allowed to be there.
There is another, widely known, way to make a binary tree from a general tree, with no "connectivity nodes".
This method can be best understood like this:
Node{ Node{
data; data;
first_child; => left;
next_sibling; right;
} }
This basically represents the list of children of the general tree as a linked list, with the addition of each node having a reference to the linked list of it's children. As you can see, this is structurally equivalent to a binary tree.
So, in pseudocode (with edge cases omitted for simplicity)
BinaryTree(gtree){
root=BinaryNode(gtree.data,BinaryNode(gtree.children),null);
}
BinaryNode(List<gnode> sibs){
BinaryNode(sibs.first.data,BinaryNode(sibs.first.children),BinaryTree(sibs.rest));
}
BinaryNode(data,left,right){
data=data;
left=left;
right=right;
}
Of course, if you need to have the structure you described, this will be useless, but in general, this is a fairly good way to create a binary tree from a general tree.