Refactor CreateBinaryTreeFromInorderPreorder (#4190)
This commit is contained in:
parent
0255705388
commit
deef2ae445
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user