BAEL-1339 - Implementing a binary tree in Java
This commit is contained in:
		
							parent
							
								
									4e39bfb945
								
							
						
					
					
						commit
						a391ecf04f
					
				
							
								
								
									
										217
									
								
								core-java/src/main/java/com/baeldung/tree/BinaryTree.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								core-java/src/main/java/com/baeldung/tree/BinaryTree.java
									
									
									
									
									
										Normal file
									
								
							| @ -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; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										141
									
								
								core-java/src/test/java/com/baeldung/tree/BinaryTreeTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								core-java/src/test/java/com/baeldung/tree/BinaryTreeTest.java
									
									
									
									
									
										Normal file
									
								
							| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user