Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added 2
Empty file.
Original file line number Diff line number Diff line change
@@ -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.
*
* <p>This implementation uses bit manipulation and mathematical observation to
* efficiently calculate the total number of set bits in O(log N) time.
*
* <p>Example:
* N = 3 -> Binary(1):01, Binary(2):10, Binary(3):11 => Total Set Bits = 4
*
* <p>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;
}
}
Original file line number Diff line number Diff line change
@@ -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.
*
* <p>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 <a href="https://en.wikipedia.org/wiki/Threaded_binary_tree">Wikipedia:
* Threaded binary tree</a>
*/
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<Integer> inorderTraversal() {
List<Integer> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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));
}
}
Original file line number Diff line number Diff line change
@@ -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<Integer> expected = List.of(20, 30, 40, 50, 60, 70, 80);
List<Integer> 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<Integer> expected = List.of(2, 3, 5, 7, 7);
List<Integer> actual = tree.inorderTraversal();

assertEquals(expected, actual);
}
}
Empty file added total
Empty file.