First Word
For BST it’s very important to do insert and delete (balancing not required).
Insertion is easy, but deletion is very difficult. However, it’s a good idea to at least know the principles.
Insert a node
Steps:
check whether new value = current node value. If not, proceed.
if new value is less, than:
if current node has no left child, set left to new value, and return
otherwise, go to left child and start over
if new value is greater, than:
if current node has no right child, set right to new value
otherwise, go to right child and start over
Note:
The BST may not be balanced after the insertion.
Code
Code snippet from this article
public boolean add(TreeNode node, int value) {
if (value == node.val)
return false;
if (value < node.val) {
if (node.left == null) {
node.left = new TreeNode(value);
return true;
} else {
return add(node.left, value);
}
} else if (value > node.val) {
if (node.right == null) {
node.right = new TreeNode(value);
return true;
} else {
return add(node.right, value);
}
}
return false;
}
Delete a node
Steps:
- Find the node
- Find the maximum node in the left subtree
- Replace the node with the maximum node in the left subtree.
Special Cases:
- The node doest have a left child.
- The maximum node in the left subtree has a left child.
- The node is the root of the tree
Code
The source code given by ninechap
private void myDeleteNode(TreeNode parent, TreeNode node) {
if (node.left == null) {
if (parent.right == node) {
parent.right = node.right;
} else {
parent.left = node.right;
}
} else {
TreeNode maxNodeParent = node;
TreeNode maxNode = node.left;
// find the maximum node in the left sub tree
while (maxNode.right != null) {
maxNodeParent = maxNode;
maxNode = maxNode.right;
}
if (maxNodeParent.left == maxNode) {
maxNodeParent.left = maxNode.left;
} else {
maxNodeParent.right = maxNode.left;
}
// move replacedNode to node
maxNode.left = node.left;
maxNode.right = node.right;
if (parent.left == node) {
parent.left = maxNode;
} else {
parent.right = maxNode;
}
}
}
private void findAndDelete(TreeNode parent, TreeNode node, int val) {
if (node == null) {
return;
}
if (node.val == val) {
myDeleteNode(parent, node);
} else if (node.val < val) {
findAndDelete(node, node.right, val);
} else {
findAndDelete(node, node.left, val);
}
}
public TreeNode deleteNode(TreeNode root, int val) {
TreeNode dummyNode = new TreeNode(0);
dummyNode.left = root;
findAndDelete(dummyNode, root, val);
return dummyNode.left;
}
A little bit on balancing
There are 2 ways to balance a tree. Most common method is tree rotation:
An AVL Trees means a self-balancing search trees. If balance gets out of range −1…+1, the subtree is rotated to bring into balance.
Second way is to convert tree into a linkedlist, then build the tree again (we have discussed this algorithm before, pick the middle element).
This method is slow if we insert and re-balance on each step, but we can do bulk insert/delete forgetting about the re-balancing for a while. This will make the data structure faster! more details