Refactor CreateBinaryTreeFromInorderPreorder (#4190)

This commit is contained in:
Albina Gimaletdinova 2023-05-14 14:52:30 +03:00 committed by GitHub
parent 0255705388
commit deef2ae445
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 157 additions and 85 deletions

View File

@ -1,6 +1,7 @@
package com.thealgorithms.datastructures.trees; package com.thealgorithms.datastructures.trees;
import com.thealgorithms.datastructures.trees.BinaryTree.Node; import com.thealgorithms.datastructures.trees.BinaryTree.Node;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -11,58 +12,29 @@ import java.util.Map;
* subtree. Based on that index create left and right subtree. Complexity: Time: * subtree. Based on that index create left and right subtree. Complexity: Time:
* O(n^2) for each node there is iteration to find index in inorder array Space: * O(n^2) for each node there is iteration to find index in inorder array Space:
* Stack size = O(height) = O(lg(n)) * Stack size = O(height) = O(lg(n))
* * <p>
* Optimized Solution: Instead of iterating over inorder array to find index of * Optimized Solution: Instead of iterating over inorder array to find index of
* root value, create a hashmap and find out the index of root value. * root value, create a hashmap and find out the index of root value.
* Complexity: Time: O(n) hashmap reduced iteration to find index in inorder * Complexity: Time: O(n) hashmap reduced iteration to find index in inorder
* array Space: O(n) space taken by hashmap * array Space: O(n) space taken by hashmap
*
*/ */
public class CreateBinaryTreeFromInorderPreorder { public class CreateBinaryTreeFromInorderPreorder {
public static Node createTree(final Integer[] preorder, final Integer[] inorder) {
public static void main(String[] args) { if (preorder == null || inorder == null) {
test(new Integer[] {}, new Integer[] {}); // empty tree return null;
test(new Integer[] { 1 }, new Integer[] { 1 }); // single node tree }
test(new Integer[] { 1, 2, 3, 4 }, new Integer[] { 1, 2, 3, 4 }); // right skewed tree return createTree(preorder, inorder, 0, 0, inorder.length);
test(new Integer[] { 1, 2, 3, 4 }, new Integer[] { 4, 3, 2, 1 }); // left skewed tree
test(
new Integer[] { 3, 9, 20, 15, 7 },
new Integer[] { 9, 3, 15, 20, 7 }
); // normal tree
} }
private static void test( public static Node createTreeOptimized(final Integer[] preorder, final Integer[] inorder) {
final Integer[] preorder, if (preorder == null || inorder == null) {
final Integer[] inorder return null;
) { }
System.out.println( Map<Integer, Integer> inorderMap = new HashMap<>();
"\n===================================================="
);
System.out.println("Naive Solution...");
BinaryTree root = new BinaryTree(
createTree(preorder, inorder, 0, 0, inorder.length)
);
System.out.println("Preorder Traversal: ");
root.preOrder(root.getRoot());
System.out.println("\nInorder Traversal: ");
root.inOrder(root.getRoot());
System.out.println("\nPostOrder Traversal: ");
root.postOrder(root.getRoot());
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < inorder.length; i++) { for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i); inorderMap.put(inorder[i], i);
} }
BinaryTree optimizedRoot = new BinaryTree( return createTreeOptimized(preorder, inorderMap, 0, 0, inorder.length);
createTreeOptimized(preorder, inorder, 0, 0, inorder.length, map)
);
System.out.println("\n\nOptimized solution...");
System.out.println("Preorder Traversal: ");
optimizedRoot.preOrder(root.getRoot());
System.out.println("\nInorder Traversal: ");
optimizedRoot.inOrder(root.getRoot());
System.out.println("\nPostOrder Traversal: ");
optimizedRoot.postOrder(root.getRoot());
} }
private static Node createTree( private static Node createTree(
@ -78,7 +50,7 @@ public class CreateBinaryTreeFromInorderPreorder {
Node root = new Node(preorder[preStart]); Node root = new Node(preorder[preStart]);
int i = inStart; int i = inStart;
while (preorder[preStart] != inorder[i]) { while (!preorder[preStart].equals(inorder[i])) {
i++; i++;
} }
int leftNodesCount = i - inStart; int leftNodesCount = i - inStart;
@ -104,11 +76,10 @@ public class CreateBinaryTreeFromInorderPreorder {
private static Node createTreeOptimized( private static Node createTreeOptimized(
final Integer[] preorder, final Integer[] preorder,
final Integer[] inorder, final Map<Integer, Integer> inorderMap,
final int preStart, final int preStart,
final int inStart, final int inStart,
final int size, final int size
final Map<Integer, Integer> inorderMap
) { ) {
if (size == 0) { if (size == 0) {
return null; return null;
@ -121,20 +92,18 @@ public class CreateBinaryTreeFromInorderPreorder {
root.left = root.left =
createTreeOptimized( createTreeOptimized(
preorder, preorder,
inorder, inorderMap,
preStart + 1, preStart + 1,
inStart, inStart,
leftNodesCount, leftNodesCount
inorderMap
); );
root.right = root.right =
createTreeOptimized( createTreeOptimized(
preorder, preorder,
inorder, inorderMap,
preStart + leftNodesCount + 1, preStart + leftNodesCount + 1,
i + 1, i + 1,
rightNodesCount, rightNodesCount
inorderMap
); );
return root; return root;
} }

View File

@ -0,0 +1,103 @@
package com.thealgorithms.datastructures.trees;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
/**
* @author Albina Gimaletdinova on 14/05/2023
*/
public class CreateBinaryTreeFromInorderPreorderTest {
@Test
public void testOnNullArraysShouldReturnNullTree() {
// when
BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(null, null);
BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(null, null);
// then
Assertions.assertNull(root);
Assertions.assertNull(rootOpt);
}
@Test
public void testOnEmptyArraysShouldCreateNullTree() {
// given
Integer[] preorder = {};
Integer[] inorder = {};
// when
BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(preorder, inorder);
BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(preorder, inorder);
// then
Assertions.assertNull(root);
Assertions.assertNull(rootOpt);
}
@Test
public void testOnSingleNodeTreeShouldCreateCorrectTree() {
// given
Integer[] preorder = {1};
Integer[] inorder = {1};
// when
BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(preorder, inorder);
BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(preorder, inorder);
// then
checkTree(preorder, inorder, root);
checkTree(preorder, inorder, rootOpt);
}
@Test
public void testOnRightSkewedTreeShouldCreateCorrectTree() {
// given
Integer[] preorder = {1, 2, 3, 4};
Integer[] inorder = {1, 2, 3, 4};
// when
BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(preorder, inorder);
BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(preorder, inorder);
// then
checkTree(preorder, inorder, root);
checkTree(preorder, inorder, rootOpt);
}
@Test
public void testOnLeftSkewedTreeShouldCreateCorrectTree() {
// given
Integer[] preorder = {1, 2, 3, 4};
Integer[] inorder = {4, 3, 2, 1};
// when
BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(preorder, inorder);
BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(preorder, inorder);
// then
checkTree(preorder, inorder, root);
checkTree(preorder, inorder, rootOpt);
}
@Test
public void testOnNormalTreeShouldCreateCorrectTree() {
// given
Integer[] preorder = {3, 9, 20, 15, 7};
Integer[] inorder = {9, 3, 15, 20, 7};
// when
BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(preorder, inorder);
BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(preorder, inorder);
// then
checkTree(preorder, inorder, root);
checkTree(preorder, inorder, rootOpt);
}
private static void checkTree(Integer[] preorder, Integer[] inorder, BinaryTree.Node root) {
Assertions.assertNotNull(root);
Assertions.assertEquals(PreOrderTraversal.iterativePreOrder(root), Arrays.asList(preorder));
Assertions.assertEquals(InorderTraversal.iterativeInorder(root), Arrays.asList(inorder));
}
}