Below is the code to delete a node in Binary Search Tree(BST)
https://leetcode.com/submissions/detail/730887683/
I have a doubt .Why are we doing below i.e why are are assigning.
root.left=deleteNode(root.left,key);
and why not
deleteNode(root.left,key);
Similarly for root.right .
Imagine a BST with 3 nodes, with the root node as 5 and the key as 3.
5
/ \
3 6
When the key is deleted from the (root)node, the (root)node.left value should become null, if it's not null then the tree remains just as it was originally.
Hence, it's important to assign the deleted "null" value to the root.left.
root.left=deleteNode(root.left,key);
Related
Is there is some algorithm to reach the grandchildren of a binary tree? Like the example?
In the picture, there are nodes linking grandparents to their grandchildren, whereas a normal binary tree only links children to parents. What algorithm would one use to link to grandparents?
EDIT:
each node has an index and two values.
[index]
[value value];
What im trying to do:
index[3] and index[4] = value[0];
index[5] and index[6] = value[1];
index[7] and index[8] = value[2];
index[9] and index[10] = value[3];
.... ETC
Typically you construct each node in a binary tree with two pointers: a left child pointer 'node.left' and a right child pointer node 'node.right'. Then the four grandchildren of a node could be located with the expressions 'node.left.left', 'node.left.right', 'node.right.left', and 'node.right.right'. These expressions will evaluate very quickly.
Accessing the grandchildren via this technique will make everything much simpler for the person who has to maintain your code, which might even be you ten months from now after you have had time to forget that you ever had this discussion.
If you insist on storing the grandchild pointers redundantly then you will need four additional pointers per node: 'node.leftleft', 'node.leftright', 'node.rightleft', and 'node.rightright'.
This feels like the very definition a bad idea. Not only will the tree be big and clumsy, but every time you add or delete a node you will find yourself updating a metric barrowload of pointers. In order to recoup the time you will spend debugging such a mess, you will have to use the program for about nine thousand years.
0
/ \
1 2
/ \ / \
3 4 5 6
[0,1,2,3,4,5,6] Binary Tree as Array
left = 2n+1
right = 2n+2
left-left-grandChild = 2(2n+1)+1 => 4n+3
left-right-grandChild = 2(2n+1)+2 => 4n+4
right-left-grandChild = 2(2n+2)+1 => 4n+5
right-right-grandChild = 2(2n+2)+2 => 4n+6
I have homeowork to write pseudo code to check if a valid binary tree is a search binary tree.
I created an array to hold the in-order values of the tree. if the in-order values are in decreasing order it means it is indeed BST. However I've got some problem with the recursion in the method InOverArr.
I need to update the index of the array in order to submit the values to the array in the order they are at the tree.
I'm not sure the index is really updated properly during the recursion.. is it or not? and if you see some problem can you help me fix this? thanks a lot
pseudo code
first function
IsBST(node)
size ← TreeSize(node)
create new array TreeArr of Size number of cells
index ← 0
few comments:
now we use the IN_ORDER procedure with a small variation , I called the new version of the procedure: InOrderArr
the pseudo code of InOrderArr is described below IsBST
InOrderArr(node, TreeArr, index)
for i from 1 to size-1 do
if not (TreeArr[i] > TreeArr[i-1]) return
false
return true
second function
InOrderArr (node, Array, index)
if node = NULL then return
else
InOrderArr (node.left, Array, index)
treeArr[index] = node.key
index ← index + 1
InOrderArr (node.right, Array, index)
Return
Your code is generally correct. Just three notes.
The correctness of the code depends on the implementation, specifically on the way of index handling. Many programming languages pass arguments to subroutines by value. That means the subroutine receives a copy of the value and modifications made to the parameter have no effect on the original value. So incrementing index during execution of InOrderArr (node.left, Array, index) would not affect the position used by treeArr[index] = node.key. As a result only the rightmost path would be stored in the array.
To avoid that you'll have to ensure that index is passed by reference, so that incrementation done by a callee advances the position used later by a caller.
BST is usually defined so that the left subtreee of a node contains keys that are less than that node's key, and the right subtree contains nodes with greater keys – see Wikipedia's article on BST. Then the inorder traversal retrieves keys in ascending order. Why do you expect descending order?
Possibly it would be more efficient to drop the array and just recursively test a definition condition of BST?
Whenever we follow a left link we expect keys which are less than the current one. Whenever we follow the right link we expect keys greater the the current one. So for most subtrees there is some interval of keys values, defined by some ancestor nodes' keys. Just track those keys and test whether the key falls inside the current valid interval. Be sure to handle 'no left end defined' condition on the letfmost path and 'no right end' on the rightmost path of the tree. At the root node there's no ancestor yet, so the root key is not tested at all (any value is OK).
EDIT
C code draft:
// Test a node against its closest left-side and right-side ancestors
boolean isNodeBST(NODE *lt, NODE *node, NODE *rt)
{
if(node == NULL)
return true;
if(lt != NULL && node->key < lt->key)
return false;
if(rt != NULL && node->key > rt->key)
return false;
return
isNodeBST(lt, node->left, node) &&
isNodeBST(node, node->right, rt);
}
boolean isTreeBST(TREE *tree)
{
return isNodeBST( NULL, tree->root, NULL);
}
Please answer on b trees and not b+ trees.
I have 2 questions.
What happens when you insert duplicated keys to a b tree?
For the following input how will the b tree with t=3 look like?
1,1,1,1,1,1,1,1,1,1,1,1,1,1
Can a parent node in a b tree with t=3 look like this?
1,1,4,10?
If so will the son between the key "1" and the second key" 1" contain only the value "1" ?
Just like hash tables, each node in the tree should store a link to a list of items associated with that key. You will store unique keys in the tree but the links will point to a list with possibly multiple items:
[node, key=1, ptr=l], l={1,1,1,1,1,1,1...}
I have a VirtualStringTree with X roots and X childnodes.
Every root has a special NodeData assigned.
Every childnode has another NodeData assigned.
How do I know OnFreeNode which is which? Cause I can't free the data without knowing which record is assigned to it.
Any Ideas?
To determine a node level use the GetNodeLevel function. It returns the 0 based level index, where 0 means a root node, 1 is for a root's child, 2 is for a root's grandchild etc.
So, in OnFreeNode event you can use something like this:
procedure TForm1.VirtualTreeFreeNode(Sender: TBaseVirtualTree;
Node: PVirtualNode);
begin
case VirtualTree.GetNodeLevel(Node) of
0: // free your root node data
1: // free your root's child node data
end;
end;
I am developing a Trie data-structure where each node represents a word. So words st, stack, stackoverflow and overflow will be arranged as
root
--st
---stack
-----stackoverflow
--overflow
My Trie uses a HashTable internally so all node lookup will take constant time. Following is the algorithm I came up to insert an item into the trie.
Check item existence in the trie. If exist, return, else goto step2.
Iterate each character in the key and check for the existence of the word. Do this until we get a node where the new value can be added as child. If no node found, it will be added under root node.
After insertion, rearrange the siblings of the node under which the new node was inserted. This will walk through all the siblings and compare against the newly inserted node. If any of the node starts with same characters that new node have, it will be moved from there and added as child of new node.
I am not sure that this is the correct way of implementing a trie. Any suggestions or improvements are welcome.
Language used : C++
The trie should look like this
ROOT
overflow/ \st
O O
\ack
O
\overflow
O
Normally you don't need to use hash tables as part of a trie; the trie itself is already an efficient index data structure. Of course you can do that.
But anyway, your step (2) should actually descend the trie during the search and not just query the hash function. In this way you find the insertion point readily and don't need to search for it later as a separate step.
I believe step (3) is wrong, you don't need to rearrange a trie and as a matter of fact you shouldn't be able to because it's only the additional string fragments that you store in the trie; see the picture above.
Following is the java code for insert algorithm.
public void insert(String s){
Node current = root;
if(s.length()==0) //For an empty character
current.marker=true;
for(int i=0;i<s.length();i++){
Node child = current.subNode(s.charAt(i));
if(child!=null){
current = child;
}
else{
current.child.add(new Node(s.charAt(i)));
current = current.subNode(s.charAt(i));
}
// Set marker to indicate end of the word
if(i==s.length()-1)
current.marker = true;
}
}
For a more detailed tutorial, refer here.