From 15bc3244303470a77481cf338ce3c73f2557475e Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 15 Dec 2017 20:26:16 +0100 Subject: [PATCH 1/4] binary tree changed to follow a recursive approach --- .../java/com/baeldung/tree/BinaryTree.java | 185 +++++++++--------- 1 file changed, 94 insertions(+), 91 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/tree/BinaryTree.java b/core-java/src/main/java/com/baeldung/tree/BinaryTree.java index 3cc496e348..0b917ed452 100644 --- a/core-java/src/main/java/com/baeldung/tree/BinaryTree.java +++ b/core-java/src/main/java/com/baeldung/tree/BinaryTree.java @@ -16,29 +16,23 @@ public class BinaryTree { return; } - Node parent = root; - Node current = root; + addRecursive(root, value); + } - while (true) { + private Node addRecursive(Node current, int value) { - 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; + if (current == null) { + return new Node(value); } + + if (value < current.value) { + current.left = addRecursive(current.left, value); + } else { + current.right = addRecursive(current.right, value); + } + + return current; + } public boolean isEmpty() { @@ -46,115 +40,107 @@ public class BinaryTree { } public boolean containsNode(int value) { + return containsNodeRecursive(root, value); + } - Node current = root; - - while (current != null) { - - if (value == current.value) { - return true; - } - - if (value < current.value) { - current = current.left; - } else { - current = current.right; - } + private boolean containsNodeRecursive(Node current, int value) { + if (current == null) { + return false; + } else if (value == current.value) { + return true; + } else if (value < current.value) { + return containsNodeRecursive(current.left, value); + } else { + return containsNodeRecursive(current.right, value); } - return false; } public void delete(int value) { - Node current = root; - Node parent = root; - Node nodeToDelete = null; - boolean isLeftChild = false; + NodeVO nodeToDeleteAux = findNodeToDelete(root, root, false, value); - 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) { + if (nodeToDeleteAux == null) { return; } // Case 1: no children - if (nodeToDelete.left == null && nodeToDelete.right == null) { - if (nodeToDelete == root) { + if (nodeToDeleteAux.node.left == null && nodeToDeleteAux.node.right == null) { + if (nodeToDeleteAux.node == root) { root = null; - } else if (isLeftChild) { - parent.left = null; + } else if (nodeToDeleteAux.isLeftChild) { + nodeToDeleteAux.parent.left = null; } else { - parent.right = null; + nodeToDeleteAux.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 if (nodeToDeleteAux.node.right == null) { + if (nodeToDeleteAux.node == root) { + root = nodeToDeleteAux.node.left; + } else if (nodeToDeleteAux.isLeftChild) { + nodeToDeleteAux.parent.left = nodeToDeleteAux.node.left; } else { - parent.right = nodeToDelete.left; + nodeToDeleteAux.parent.right = nodeToDeleteAux.node.left; } - } else if (nodeToDelete.left == null) { - if (nodeToDelete == root) { - root = nodeToDelete.right; - } else if (isLeftChild) { - parent.left = nodeToDelete.right; + } else if (nodeToDeleteAux.node.left == null) { + if (nodeToDeleteAux.node == root) { + root = nodeToDeleteAux.node.right; + } else if (nodeToDeleteAux.isLeftChild) { + nodeToDeleteAux.parent.left = nodeToDeleteAux.node.right; } else { - parent.right = nodeToDelete.right; + nodeToDeleteAux.parent.right = nodeToDeleteAux.node.right; } } // Case 3: 2 children - else if (nodeToDelete.left != null && nodeToDelete.right != null) { - Node replacement = findReplacement(nodeToDelete); - if (nodeToDelete == root) { + else if (nodeToDeleteAux.node.left != null && nodeToDeleteAux.node.right != null) { + Node replacement = findReplacement(nodeToDeleteAux.node); + if (nodeToDeleteAux.node == root) { root = replacement; - } else if (isLeftChild) { - parent.left = replacement; + } else if (nodeToDeleteAux.isLeftChild) { + nodeToDeleteAux.parent.left = replacement; } else { - parent.right = replacement; + nodeToDeleteAux.parent.right = replacement; } } } + private NodeVO findNodeToDelete(Node current, Node parent, boolean isLeftChild, int value) { + + if (current == null) { + return null; + } else if (value == current.value) { + return new NodeVO(current, parent, isLeftChild); + } else if (value < current.value) { + return findNodeToDelete(current.left, current, true, value); + } else { + return findNodeToDelete(current.right, current, false, value); + } + } + private Node findReplacement(Node nodeToDelete) { - Node replacement = nodeToDelete; - Node parentReplacement = nodeToDelete; - Node current = nodeToDelete.right; + NodeVO replacementNodeVO = findSmallestNode(nodeToDelete, nodeToDelete); - while (current != null) { - parentReplacement = replacement; - replacement = current; - current = current.left; + if (replacementNodeVO.node != nodeToDelete.right) { + replacementNodeVO.parent.left = replacementNodeVO.node.right; + replacementNodeVO.node.right = nodeToDelete.right; } - if (replacement != nodeToDelete.right) { - parentReplacement.left = replacement.right; - replacement.right = nodeToDelete.right; + replacementNodeVO.node.left = nodeToDelete.left; + + return replacementNodeVO.node; + } + + private NodeVO findSmallestNode(Node root, Node parent) { + + if (root.left == null) { + return new NodeVO(root, parent); } - replacement.left = nodeToDelete.left; - - return replacement; + return findSmallestNode(root.left, root); } public void traverseInOrder(Node node) { @@ -202,6 +188,23 @@ public class BinaryTree { } } + class NodeVO { + Node node; + Node parent; + boolean isLeftChild; + + NodeVO(Node node, Node parent) { + this.node = node; + this.parent = parent; + } + + NodeVO(Node node, Node parent, boolean isLeftChild) { + this.node = node; + this.parent = parent; + this.isLeftChild = isLeftChild; + } + } + class Node { int value; Node left; From 9ead70be1bbab8515d4abdf7205b1eea79f5f11b Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 15 Dec 2017 20:42:56 +0100 Subject: [PATCH 2/4] var renamed --- .../java/com/baeldung/tree/BinaryTree.java | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/tree/BinaryTree.java b/core-java/src/main/java/com/baeldung/tree/BinaryTree.java index 0b917ed452..686136729e 100644 --- a/core-java/src/main/java/com/baeldung/tree/BinaryTree.java +++ b/core-java/src/main/java/com/baeldung/tree/BinaryTree.java @@ -59,49 +59,49 @@ public class BinaryTree { public void delete(int value) { - NodeVO nodeToDeleteAux = findNodeToDelete(root, root, false, value); + NodeVO nodeToDeleteVO = findNodeToDelete(root, root, false, value); - if (nodeToDeleteAux == null) { + if (nodeToDeleteVO == null) { return; } // Case 1: no children - if (nodeToDeleteAux.node.left == null && nodeToDeleteAux.node.right == null) { - if (nodeToDeleteAux.node == root) { + if (nodeToDeleteVO.node.left == null && nodeToDeleteVO.node.right == null) { + if (nodeToDeleteVO.node == root) { root = null; - } else if (nodeToDeleteAux.isLeftChild) { - nodeToDeleteAux.parent.left = null; + } else if (nodeToDeleteVO.isLeftChild) { + nodeToDeleteVO.parent.left = null; } else { - nodeToDeleteAux.parent.right = null; + nodeToDeleteVO.parent.right = null; } } // Case 2: only 1 child - else if (nodeToDeleteAux.node.right == null) { - if (nodeToDeleteAux.node == root) { - root = nodeToDeleteAux.node.left; - } else if (nodeToDeleteAux.isLeftChild) { - nodeToDeleteAux.parent.left = nodeToDeleteAux.node.left; + else if (nodeToDeleteVO.node.right == null) { + if (nodeToDeleteVO.node == root) { + root = nodeToDeleteVO.node.left; + } else if (nodeToDeleteVO.isLeftChild) { + nodeToDeleteVO.parent.left = nodeToDeleteVO.node.left; } else { - nodeToDeleteAux.parent.right = nodeToDeleteAux.node.left; + nodeToDeleteVO.parent.right = nodeToDeleteVO.node.left; } - } else if (nodeToDeleteAux.node.left == null) { - if (nodeToDeleteAux.node == root) { - root = nodeToDeleteAux.node.right; - } else if (nodeToDeleteAux.isLeftChild) { - nodeToDeleteAux.parent.left = nodeToDeleteAux.node.right; + } else if (nodeToDeleteVO.node.left == null) { + if (nodeToDeleteVO.node == root) { + root = nodeToDeleteVO.node.right; + } else if (nodeToDeleteVO.isLeftChild) { + nodeToDeleteVO.parent.left = nodeToDeleteVO.node.right; } else { - nodeToDeleteAux.parent.right = nodeToDeleteAux.node.right; + nodeToDeleteVO.parent.right = nodeToDeleteVO.node.right; } } // Case 3: 2 children - else if (nodeToDeleteAux.node.left != null && nodeToDeleteAux.node.right != null) { - Node replacement = findReplacement(nodeToDeleteAux.node); - if (nodeToDeleteAux.node == root) { + else if (nodeToDeleteVO.node.left != null && nodeToDeleteVO.node.right != null) { + Node replacement = findReplacement(nodeToDeleteVO.node); + if (nodeToDeleteVO.node == root) { root = replacement; - } else if (nodeToDeleteAux.isLeftChild) { - nodeToDeleteAux.parent.left = replacement; + } else if (nodeToDeleteVO.isLeftChild) { + nodeToDeleteVO.parent.left = replacement; } else { - nodeToDeleteAux.parent.right = replacement; + nodeToDeleteVO.parent.right = replacement; } } From 7acbc7902d109fb3252fa8518c96e53a1ac8af66 Mon Sep 17 00:00:00 2001 From: Marcos Date: Sat, 16 Dec 2017 12:33:50 +0100 Subject: [PATCH 3/4] recursived deletion binary tree --- .../java/com/baeldung/tree/BinaryTree.java | 119 +++++------------- 1 file changed, 32 insertions(+), 87 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/tree/BinaryTree.java b/core-java/src/main/java/com/baeldung/tree/BinaryTree.java index 686136729e..d5ccd05bdb 100644 --- a/core-java/src/main/java/com/baeldung/tree/BinaryTree.java +++ b/core-java/src/main/java/com/baeldung/tree/BinaryTree.java @@ -58,89 +58,51 @@ public class BinaryTree { } public void delete(int value) { - - NodeVO nodeToDeleteVO = findNodeToDelete(root, root, false, value); - - if (nodeToDeleteVO == null) { - return; - } - - // Case 1: no children - if (nodeToDeleteVO.node.left == null && nodeToDeleteVO.node.right == null) { - if (nodeToDeleteVO.node == root) { - root = null; - } else if (nodeToDeleteVO.isLeftChild) { - nodeToDeleteVO.parent.left = null; - } else { - nodeToDeleteVO.parent.right = null; - } - } - // Case 2: only 1 child - else if (nodeToDeleteVO.node.right == null) { - if (nodeToDeleteVO.node == root) { - root = nodeToDeleteVO.node.left; - } else if (nodeToDeleteVO.isLeftChild) { - nodeToDeleteVO.parent.left = nodeToDeleteVO.node.left; - } else { - nodeToDeleteVO.parent.right = nodeToDeleteVO.node.left; - } - } else if (nodeToDeleteVO.node.left == null) { - if (nodeToDeleteVO.node == root) { - root = nodeToDeleteVO.node.right; - } else if (nodeToDeleteVO.isLeftChild) { - nodeToDeleteVO.parent.left = nodeToDeleteVO.node.right; - } else { - nodeToDeleteVO.parent.right = nodeToDeleteVO.node.right; - } - } - // Case 3: 2 children - else if (nodeToDeleteVO.node.left != null && nodeToDeleteVO.node.right != null) { - Node replacement = findReplacement(nodeToDeleteVO.node); - if (nodeToDeleteVO.node == root) { - root = replacement; - } else if (nodeToDeleteVO.isLeftChild) { - nodeToDeleteVO.parent.left = replacement; - } else { - nodeToDeleteVO.parent.right = replacement; - } - } - + deleteRecursive(root, value); } - private NodeVO findNodeToDelete(Node current, Node parent, boolean isLeftChild, int value) { - + private Node deleteRecursive(Node current, int value) { if (current == null) { return null; - } else if (value == current.value) { - return new NodeVO(current, parent, isLeftChild); + } + + if (value == current.value) { + // Case 1: no children + if (current.left == null && current.right == null) { + return null; + } + + // Case 2: only 1 child + if (current.right == null) { + return current.left; + } + + if (current.left == null) { + return current.right; + } + + // Case 3: 2 children + int smallestValue = findSmallestNode(current.right); + current.value = smallestValue; + current.right = deleteRecursive(current.right, smallestValue); + return current; + } else if (value < current.value) { - return findNodeToDelete(current.left, current, true, value); + current.left = deleteRecursive(current.left, value); + return current; } else { - return findNodeToDelete(current.right, current, false, value); + current.right = deleteRecursive(current.right, value); + return current; } } - private Node findReplacement(Node nodeToDelete) { - - NodeVO replacementNodeVO = findSmallestNode(nodeToDelete, nodeToDelete); - - if (replacementNodeVO.node != nodeToDelete.right) { - replacementNodeVO.parent.left = replacementNodeVO.node.right; - replacementNodeVO.node.right = nodeToDelete.right; - } - - replacementNodeVO.node.left = nodeToDelete.left; - - return replacementNodeVO.node; - } - - private NodeVO findSmallestNode(Node root, Node parent) { + private int findSmallestNode(Node root) { if (root.left == null) { - return new NodeVO(root, parent); + return root.value; } - return findSmallestNode(root.left, root); + return findSmallestNode(root.left); } public void traverseInOrder(Node node) { @@ -188,23 +150,6 @@ public class BinaryTree { } } - class NodeVO { - Node node; - Node parent; - boolean isLeftChild; - - NodeVO(Node node, Node parent) { - this.node = node; - this.parent = parent; - } - - NodeVO(Node node, Node parent, boolean isLeftChild) { - this.node = node; - this.parent = parent; - this.isLeftChild = isLeftChild; - } - } - class Node { int value; Node left; From 959845621fc23dbb411b8f8585042a797dc84dde Mon Sep 17 00:00:00 2001 From: Marcos Date: Sat, 16 Dec 2017 12:37:30 +0100 Subject: [PATCH 4/4] refactor --- core-java/src/main/java/com/baeldung/tree/BinaryTree.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/tree/BinaryTree.java b/core-java/src/main/java/com/baeldung/tree/BinaryTree.java index d5ccd05bdb..285dc12219 100644 --- a/core-java/src/main/java/com/baeldung/tree/BinaryTree.java +++ b/core-java/src/main/java/com/baeldung/tree/BinaryTree.java @@ -82,7 +82,7 @@ public class BinaryTree { } // Case 3: 2 children - int smallestValue = findSmallestNode(current.right); + int smallestValue = findSmallestValue(current.right); current.value = smallestValue; current.right = deleteRecursive(current.right, smallestValue); return current; @@ -96,13 +96,13 @@ public class BinaryTree { } } - private int findSmallestNode(Node root) { + private int findSmallestValue(Node root) { if (root.left == null) { return root.value; } - return findSmallestNode(root.left); + return findSmallestValue(root.left); } public void traverseInOrder(Node node) {