BAEL-1339 - Implementing a binary tree in Java
This commit is contained in:
parent
4e39bfb945
commit
a391ecf04f
|
@ -0,0 +1,217 @@
|
|||
package com.baeldung.tree;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class BinaryTree {
|
||||
|
||||
Node root;
|
||||
|
||||
public void add(int value) {
|
||||
|
||||
Node newNode = new Node(value);
|
||||
|
||||
if (root == null) {
|
||||
root = newNode;
|
||||
return;
|
||||
}
|
||||
|
||||
Node parent = root;
|
||||
Node current = root;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (newNode.value < parent.value) {
|
||||
current = parent.left;
|
||||
|
||||
if (current == null) {
|
||||
parent.left = newNode;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
current = parent.right;
|
||||
|
||||
if (current == null) {
|
||||
parent.right = newNode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
parent = current;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return root == null;
|
||||
}
|
||||
|
||||
public boolean containsNode(int value) {
|
||||
|
||||
Node current = root;
|
||||
|
||||
while (current != null) {
|
||||
|
||||
if (value == current.value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value < current.value) {
|
||||
current = current.left;
|
||||
} else {
|
||||
current = current.right;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void delete(int value) {
|
||||
|
||||
Node current = root;
|
||||
Node parent = root;
|
||||
Node nodeToDelete = null;
|
||||
boolean isLeftChild = false;
|
||||
|
||||
while (nodeToDelete == null && current != null) {
|
||||
|
||||
if (value == current.value) {
|
||||
nodeToDelete = current;
|
||||
} else if (value < current.value) {
|
||||
parent = current;
|
||||
current = current.left;
|
||||
isLeftChild = true;
|
||||
} else {
|
||||
parent = current;
|
||||
current = current.right;
|
||||
isLeftChild = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (nodeToDelete == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Case 1: no children
|
||||
if (nodeToDelete.left == null && nodeToDelete.right == null) {
|
||||
if (nodeToDelete == root) {
|
||||
root = null;
|
||||
} else if (isLeftChild) {
|
||||
parent.left = null;
|
||||
} else {
|
||||
parent.right = null;
|
||||
}
|
||||
}
|
||||
// Case 2: only 1 child
|
||||
else if (nodeToDelete.right == null) {
|
||||
if (nodeToDelete == root) {
|
||||
root = nodeToDelete.left;
|
||||
} else if (isLeftChild) {
|
||||
parent.left = nodeToDelete.left;
|
||||
} else {
|
||||
parent.right = nodeToDelete.left;
|
||||
}
|
||||
} else if (nodeToDelete.left == null) {
|
||||
if (nodeToDelete == root) {
|
||||
root = nodeToDelete.right;
|
||||
} else if (isLeftChild) {
|
||||
parent.left = nodeToDelete.right;
|
||||
} else {
|
||||
parent.right = nodeToDelete.right;
|
||||
}
|
||||
}
|
||||
// Case 3: 2 children
|
||||
else if (nodeToDelete.left != null && nodeToDelete.right != null) {
|
||||
Node replacement = findReplacement(nodeToDelete);
|
||||
if (nodeToDelete == root) {
|
||||
root = replacement;
|
||||
} else if (isLeftChild) {
|
||||
parent.left = replacement;
|
||||
} else {
|
||||
parent.right = replacement;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Node findReplacement(Node nodeToDelete) {
|
||||
|
||||
Node replacement = nodeToDelete;
|
||||
Node parentReplacement = nodeToDelete;
|
||||
Node current = nodeToDelete.right;
|
||||
|
||||
while (current != null) {
|
||||
parentReplacement = replacement;
|
||||
replacement = current;
|
||||
current = current.left;
|
||||
}
|
||||
|
||||
if (replacement != nodeToDelete.right) {
|
||||
parentReplacement.left = replacement.right;
|
||||
replacement.right = nodeToDelete.right;
|
||||
}
|
||||
|
||||
replacement.left = nodeToDelete.left;
|
||||
|
||||
return replacement;
|
||||
}
|
||||
|
||||
public void traverseInOrder(Node node) {
|
||||
if (node != null) {
|
||||
traverseInOrder(node.left);
|
||||
System.out.print(" " + node.value);
|
||||
traverseInOrder(node.right);
|
||||
}
|
||||
}
|
||||
|
||||
public void traversePreOrder(Node node) {
|
||||
if (node != null) {
|
||||
System.out.print(" " + node.value);
|
||||
traversePreOrder(node.left);
|
||||
traversePreOrder(node.right);
|
||||
}
|
||||
}
|
||||
|
||||
public void traversePostOrder(Node node) {
|
||||
if (node != null) {
|
||||
traversePostOrder(node.left);
|
||||
traversePostOrder(node.right);
|
||||
|
||||
System.out.print(" " + node.value);
|
||||
}
|
||||
}
|
||||
|
||||
public void traverseLevelOrder() {
|
||||
Queue<Node> nodes = new LinkedList<>();
|
||||
nodes.add(root);
|
||||
|
||||
while (!nodes.isEmpty()) {
|
||||
|
||||
Node node = nodes.remove();
|
||||
|
||||
System.out.print(" " + node.value);
|
||||
|
||||
if (node.left != null) {
|
||||
nodes.add(node.left);
|
||||
}
|
||||
|
||||
if (node.left != null) {
|
||||
nodes.add(node.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Node {
|
||||
int value;
|
||||
Node left;
|
||||
Node right;
|
||||
|
||||
Node(int value) {
|
||||
this.value = value;
|
||||
right = null;
|
||||
left = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
package com.baeldung.tree;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class BinaryTreeTest {
|
||||
|
||||
@Test
|
||||
public void givenABinaryTree_WhenAddElements_ThenTreeNotEmpty() {
|
||||
|
||||
BinaryTree bt = new BinaryTree();
|
||||
|
||||
bt.add(6);
|
||||
bt.add(4);
|
||||
bt.add(8);
|
||||
bt.add(3);
|
||||
bt.add(5);
|
||||
bt.add(7);
|
||||
bt.add(9);
|
||||
|
||||
assertTrue(!bt.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenABinaryTree_WhenAddElements_ThenTreeContainsThoseElements() {
|
||||
|
||||
BinaryTree bt = new BinaryTree();
|
||||
|
||||
bt.add(6);
|
||||
bt.add(4);
|
||||
bt.add(8);
|
||||
bt.add(3);
|
||||
bt.add(5);
|
||||
bt.add(7);
|
||||
bt.add(9);
|
||||
|
||||
assertTrue(bt.containsNode(6));
|
||||
assertTrue(bt.containsNode(4));
|
||||
assertTrue(bt.containsNode(8));
|
||||
assertTrue(bt.containsNode(3));
|
||||
assertTrue(bt.containsNode(5));
|
||||
assertTrue(bt.containsNode(7));
|
||||
assertTrue(bt.containsNode(9));
|
||||
|
||||
assertFalse(bt.containsNode(1));
|
||||
assertFalse(bt.containsNode(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenABinaryTree_WhenDeletingElements_ThenTreeDoesNotContainThoseElements() {
|
||||
|
||||
BinaryTree bt = new BinaryTree();
|
||||
|
||||
bt.add(6);
|
||||
bt.add(4);
|
||||
bt.add(8);
|
||||
bt.add(3);
|
||||
bt.add(5);
|
||||
bt.add(7);
|
||||
bt.add(9);
|
||||
|
||||
assertTrue(bt.containsNode(9));
|
||||
bt.delete(9);
|
||||
assertFalse(bt.containsNode(9));
|
||||
|
||||
assertTrue(bt.containsNode(6));
|
||||
bt.delete(6);
|
||||
assertFalse(bt.containsNode(6));
|
||||
|
||||
assertTrue(bt.containsNode(4));
|
||||
bt.delete(4);
|
||||
assertFalse(bt.containsNode(4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenABinaryTree_WhenTraversingInOrder_ThenPrintValues() {
|
||||
|
||||
BinaryTree bt = new BinaryTree();
|
||||
|
||||
bt.add(6);
|
||||
bt.add(4);
|
||||
bt.add(8);
|
||||
bt.add(3);
|
||||
bt.add(5);
|
||||
bt.add(7);
|
||||
bt.add(9);
|
||||
|
||||
bt.traverseInOrder(bt.root);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenABinaryTree_WhenTraversingPreOrder_ThenPrintValues() {
|
||||
|
||||
BinaryTree bt = new BinaryTree();
|
||||
|
||||
bt.add(6);
|
||||
bt.add(4);
|
||||
bt.add(8);
|
||||
bt.add(3);
|
||||
bt.add(5);
|
||||
bt.add(7);
|
||||
bt.add(9);
|
||||
|
||||
bt.traversePreOrder(bt.root);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenABinaryTree_WhenTraversingPostOrder_ThenPrintValues() {
|
||||
|
||||
BinaryTree bt = new BinaryTree();
|
||||
|
||||
bt.add(6);
|
||||
bt.add(4);
|
||||
bt.add(8);
|
||||
bt.add(3);
|
||||
bt.add(5);
|
||||
bt.add(7);
|
||||
bt.add(9);
|
||||
|
||||
bt.traversePostOrder(bt.root);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenABinaryTree_WhenTraversingLevelOrder_ThenPrintValues() {
|
||||
|
||||
BinaryTree bt = new BinaryTree();
|
||||
|
||||
bt.add(6);
|
||||
bt.add(4);
|
||||
bt.add(8);
|
||||
bt.add(3);
|
||||
bt.add(5);
|
||||
bt.add(7);
|
||||
bt.add(9);
|
||||
|
||||
bt.traverseLevelOrder();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue