diff --git a/2 b/2 new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/main/java/com/thealgorithms/bitmanipulation/CountTotalSetBits.java b/src/main/java/com/thealgorithms/bitmanipulation/CountTotalSetBits.java new file mode 100644 index 000000000000..512e93d510d4 --- /dev/null +++ b/src/main/java/com/thealgorithms/bitmanipulation/CountTotalSetBits.java @@ -0,0 +1,49 @@ +package com.thealgorithms.bitmanipulation; + +/** + * Count the total number of set bits in binary representations of all numbers from 1 to N. + * + *

This implementation uses bit manipulation and mathematical observation to + * efficiently calculate the total number of set bits in O(log N) time. + * + *

Example: + * N = 3 -> Binary(1):01, Binary(2):10, Binary(3):11 => Total Set Bits = 4 + * + *

Reference: https://www.geeksforgeeks.org/count-total-set-bits-in-all-numbers-from-1-to-n/ + */ +public final class CountTotalSetBits { + + private CountTotalSetBits() { + // utility class + } + + /** + * Returns the total count of set bits in binary representations of all numbers from 1 to n. + * + * @param n the upper limit of the range + * @return total number of set bits from 1 to n + */ + public static int countTotalSetBits(int n) { + if (n == 0) { + return 0; + } + + int x = largestPowerOf2(n); + int bitsTill2x = x * (1 << (x - 1)); + int msbBits = n - (1 << x) + 1; + int rest = n - (1 << x); + + return bitsTill2x + msbBits + countTotalSetBits(rest); + } + + /** + * Helper function to find the largest power of 2 less than or equal to n. + */ + private static int largestPowerOf2(int n) { + int x = 0; + while ((1 << x) <= n) { + x++; + } + return x - 1; + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTree.java b/src/main/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTree.java new file mode 100644 index 000000000000..fd8876cecb70 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTree.java @@ -0,0 +1,145 @@ +/* + * TheAlgorithms (https://github.com/TheAlgorithms/Java) + * Author: Shewale41 + * This file is licensed under the MIT License. + */ + +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayList; +import java.util.List; + +/** + * Threaded binary tree implementation that supports insertion and + * in-order traversal without recursion or stack by using threads. + * + *

In this implementation, a node's null left/right pointers are used + * to point to the in-order predecessor/successor respectively. Two flags + * indicate whether left/right pointers are real children or threads. + * + * @see Wikipedia: + * Threaded binary tree + */ +public final class ThreadedBinaryTree { + + private Node root; + + private static final class Node { + int value; + Node left; + Node right; + boolean leftIsThread; + boolean rightIsThread; + + Node(int value) { + this.value = value; + this.left = null; + this.right = null; + this.leftIsThread = false; + this.rightIsThread = false; + } + } + + public ThreadedBinaryTree() { + this.root = null; + } + + /** + * Inserts a value into the threaded binary tree. Duplicate values are inserted + * to the right subtree (consistent deterministic rule). + * + * @param value the integer value to insert + */ + public void insert(int value) { + Node newNode = new Node(value); + if (root == null) { + root = newNode; + return; + } + + Node current = root; + Node parent = null; + + while (true) { + parent = current; + if (value < current.value) { + if (!current.leftIsThread && current.left != null) { + current = current.left; + } else { + break; + } + } else { // value >= current.value + if (!current.rightIsThread && current.right != null) { + current = current.right; + } else { + break; + } + } + } + + if (value < parent.value) { + // attach newNode as left child + newNode.left = parent.left; + newNode.leftIsThread = parent.leftIsThread; + newNode.right = parent; + newNode.rightIsThread = true; + + parent.left = newNode; + parent.leftIsThread = false; + } else { + // attach newNode as right child + newNode.right = parent.right; + newNode.rightIsThread = parent.rightIsThread; + newNode.left = parent; + newNode.leftIsThread = true; + + parent.right = newNode; + parent.rightIsThread = false; + } + } + + /** + * Returns the in-order traversal of the tree as a list of integers. + * Traversal is done without recursion or an explicit stack by following threads. + * + * @return list containing the in-order sequence of node values + */ + public List inorderTraversal() { + List result = new ArrayList<>(); + Node current = root; + if (current == null) { + return result; + } + + // Move to the leftmost node + while (current.left != null && !current.leftIsThread) { + current = current.left; + } + + while (current != null) { + result.add(current.value); + + // If right pointer is a thread, follow it + if (current.rightIsThread) { + current = current.right; + } else { + // Move to leftmost node in right subtree + current = current.right; + while (current != null && !current.leftIsThread && current.left != null) { + current = current.left; + } + } + } + + return result; + } + + /** + * Helper: checks whether the tree is empty. + * + * @return true if tree has no nodes + */ + public boolean isEmpty() { + return root == null; + } +} diff --git a/src/test/java/com/thealgorithms/bitmanipulation/CountTotalSetBitsTest.java b/src/test/java/com/thealgorithms/bitmanipulation/CountTotalSetBitsTest.java new file mode 100644 index 000000000000..33bc0ec4eaf8 --- /dev/null +++ b/src/test/java/com/thealgorithms/bitmanipulation/CountTotalSetBitsTest.java @@ -0,0 +1,32 @@ +package com.thealgorithms.bitmanipulation; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * Test cases for {@link CountTotalSetBits}. + */ +public class CountTotalSetBitsTest { + + @Test + void testSmallNumbers() { + assertEquals(4, CountTotalSetBits.countTotalSetBits(3)); // 1->1,2->1,3->2 + assertEquals(5, CountTotalSetBits.countTotalSetBits(4)); // 1,2,3,4 -> total 5 + } + + @Test + void testPowerOfTwo() { + assertEquals(12, CountTotalSetBits.countTotalSetBits(7)); // from 1 to 7 + } + + @Test + void testLargerNumber() { + assertEquals(17, CountTotalSetBits.countTotalSetBits(10)); // verified manually + } + + @Test + void testZero() { + assertEquals(0, CountTotalSetBits.countTotalSetBits(0)); + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTreeTest.java b/src/test/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTreeTest.java new file mode 100644 index 000000000000..c5973168438e --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTreeTest.java @@ -0,0 +1,50 @@ +/* + * TheAlgorithms (https://github.com/TheAlgorithms/Java) + * Author: Shewale41 + * This file is licensed under the MIT License. + */ + +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; +import org.junit.jupiter.api.Test; + +/** + * Basic tests for ThreadedBinaryTree inorder traversal. + */ +public class ThreadedBinaryTreeTest { + + @Test + public void testInorderTraversalSimple() { + ThreadedBinaryTree tree = new ThreadedBinaryTree(); + tree.insert(50); + tree.insert(30); + tree.insert(70); + tree.insert(20); + tree.insert(40); + tree.insert(60); + tree.insert(80); + + List expected = List.of(20, 30, 40, 50, 60, 70, 80); + List actual = tree.inorderTraversal(); + + assertEquals(expected, actual); + } + + @Test + public void testInorderWithDuplicates() { + ThreadedBinaryTree tree = new ThreadedBinaryTree(); + tree.insert(5); + tree.insert(3); + tree.insert(7); + tree.insert(7); // duplicate + tree.insert(2); + + List expected = List.of(2, 3, 5, 7, 7); + List actual = tree.inorderTraversal(); + + assertEquals(expected, actual); + } +} diff --git a/total b/total new file mode 100644 index 000000000000..e69de29bb2d1