diff --git a/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java b/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java new file mode 100644 index 000000000000..9026fdfaa041 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java @@ -0,0 +1,70 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.*; + +/** + * Given a binary tree. + * This code returns the zigzag level order traversal of its nodes' values. + * Binary tree: + * 7 + * / \ + * 6 3 + * / \ / \ + * 2 4 10 19 + * Zigzag traversal: + * [[7], [3, 6], [2, 4, 10, 19]] + *

+ * This solution implements the breadth-first search (BFS) algorithm using a queue. + * 1. The algorithm starts with a root node. This node is added to a queue. + * 2. While the queue is not empty: + * - each time we enter the while-loop we get queue size. Queue size refers to the number of nodes at the current level. + * - we traverse all the level nodes in 2 ways: from left to right OR from right to left + * (this state is stored on `prevLevelFromLeftToRight` variable) + * - if the current node has children we add them to a queue + * - add level with nodes to a result. + *

+ * Complexities: + * O(N) - time, where N is the number of nodes in a binary tree + * O(N) - space, where N is the number of nodes in a binary tree + * + * @author Albina Gimaletdinova on 11/01/2023 + */ +public class ZigzagTraversal { + public static List> traverse(BinaryTree.Node root) { + if (root == null) { + return new ArrayList<>(); + } + + List> result = new ArrayList<>(); + + // create a queue + Deque q = new ArrayDeque<>(); + q.offer(root); + // start with writing nodes from left to right + boolean prevLevelFromLeftToRight = false; + + while (!q.isEmpty()) { + int nodesOnLevel = q.size(); + List level = new LinkedList<>(); + // traverse all the level nodes + for (int i = 0; i < nodesOnLevel; i++) { + BinaryTree.Node node = q.poll(); + if (prevLevelFromLeftToRight) { + level.add(0, node.data); + } else { + level.add(node.data); + } + if (node.left != null) { + q.offer(node.left); + } + if (node.right != null) { + q.offer(node.right); + } + } + // the next level node traversal will be from the other side + prevLevelFromLeftToRight = !prevLevelFromLeftToRight; + result.add(level); + } + return result; + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/trees/ZigzagTraversalTest.java b/src/test/java/com/thealgorithms/datastructures/trees/ZigzagTraversalTest.java new file mode 100644 index 000000000000..11af07c57e0a --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/trees/ZigzagTraversalTest.java @@ -0,0 +1,30 @@ +package com.thealgorithms.datastructures.trees; + +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Albina Gimaletdinova on 11/01/2023 + */ +public class ZigzagTraversalTest { + @Test + public void testRootNull() { + assertEquals(Collections.emptyList(), ZigzagTraversal.traverse(null)); + } + + @Test + public void testSingleNodeTree() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[]{50}); + assertEquals(List.of(List.of(50)), ZigzagTraversal.traverse(root)); + } + + @Test + public void testZigzagTraversal() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[]{7, 6, 14, 2, 80, 100}); + assertEquals(List.of(List.of(7), List.of(14, 6), List.of(2, 80, 100)), ZigzagTraversal.traverse(root)); + } +}