Skip to content

Commit 14c0b08

Browse files
authored
Added threaded binary tree (#6995)
* Add One-Time Pad Cipher implementation in Java * Add One-Time Pad Cipher implementation (fixed) * Add ThreadedBinaryTree with in-order traversal and tests * feat: add threaded binary tree implementation and tests * fix: remove redundant null check for SpotBugs compliance
1 parent ac6fef1 commit 14c0b08

File tree

2 files changed

+195
-0
lines changed

2 files changed

+195
-0
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* TheAlgorithms (https://github.com/TheAlgorithms/Java)
3+
* Author: Shewale41
4+
* This file is licensed under the MIT License.
5+
*/
6+
7+
package com.thealgorithms.datastructures.trees;
8+
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
12+
/**
13+
* Threaded binary tree implementation that supports insertion and
14+
* in-order traversal without recursion or stack by using threads.
15+
*
16+
* <p>In this implementation, a node's null left/right pointers are used
17+
* to point to the in-order predecessor/successor respectively. Two flags
18+
* indicate whether left/right pointers are real children or threads.
19+
*
20+
* @see <a href="https://en.wikipedia.org/wiki/Threaded_binary_tree">Wikipedia:
21+
* Threaded binary tree</a>
22+
*/
23+
public final class ThreadedBinaryTree {
24+
25+
private Node root;
26+
27+
private static final class Node {
28+
int value;
29+
Node left;
30+
Node right;
31+
boolean leftIsThread;
32+
boolean rightIsThread;
33+
34+
Node(int value) {
35+
this.value = value;
36+
this.left = null;
37+
this.right = null;
38+
this.leftIsThread = false;
39+
this.rightIsThread = false;
40+
}
41+
}
42+
43+
public ThreadedBinaryTree() {
44+
this.root = null;
45+
}
46+
47+
/**
48+
* Inserts a value into the threaded binary tree. Duplicate values are inserted
49+
* to the right subtree (consistent deterministic rule).
50+
*
51+
* @param value the integer value to insert
52+
*/
53+
public void insert(int value) {
54+
Node newNode = new Node(value);
55+
if (root == null) {
56+
root = newNode;
57+
return;
58+
}
59+
60+
Node current = root;
61+
Node parent = null;
62+
63+
while (true) {
64+
parent = current;
65+
if (value < current.value) {
66+
if (!current.leftIsThread && current.left != null) {
67+
current = current.left;
68+
} else {
69+
break;
70+
}
71+
} else { // value >= current.value
72+
if (!current.rightIsThread && current.right != null) {
73+
current = current.right;
74+
} else {
75+
break;
76+
}
77+
}
78+
}
79+
80+
if (value < parent.value) {
81+
// attach newNode as left child
82+
newNode.left = parent.left;
83+
newNode.leftIsThread = parent.leftIsThread;
84+
newNode.right = parent;
85+
newNode.rightIsThread = true;
86+
87+
parent.left = newNode;
88+
parent.leftIsThread = false;
89+
} else {
90+
// attach newNode as right child
91+
newNode.right = parent.right;
92+
newNode.rightIsThread = parent.rightIsThread;
93+
newNode.left = parent;
94+
newNode.leftIsThread = true;
95+
96+
parent.right = newNode;
97+
parent.rightIsThread = false;
98+
}
99+
}
100+
101+
/**
102+
* Returns the in-order traversal of the tree as a list of integers.
103+
* Traversal is done without recursion or an explicit stack by following threads.
104+
*
105+
* @return list containing the in-order sequence of node values
106+
*/
107+
public List<Integer> inorderTraversal() {
108+
List<Integer> result = new ArrayList<>();
109+
Node current = root;
110+
if (current == null) {
111+
return result;
112+
}
113+
114+
// Move to the leftmost node
115+
while (current.left != null && !current.leftIsThread) {
116+
current = current.left;
117+
}
118+
119+
while (current != null) {
120+
result.add(current.value);
121+
122+
// If right pointer is a thread, follow it
123+
if (current.rightIsThread) {
124+
current = current.right;
125+
} else {
126+
// Move to leftmost node in right subtree
127+
current = current.right;
128+
while (current != null && !current.leftIsThread && current.left != null) {
129+
current = current.left;
130+
}
131+
}
132+
}
133+
134+
return result;
135+
}
136+
137+
/**
138+
* Helper: checks whether the tree is empty.
139+
*
140+
* @return true if tree has no nodes
141+
*/
142+
public boolean isEmpty() {
143+
return root == null;
144+
}
145+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* TheAlgorithms (https://github.com/TheAlgorithms/Java)
3+
* Author: Shewale41
4+
* This file is licensed under the MIT License.
5+
*/
6+
7+
package com.thealgorithms.datastructures.trees;
8+
9+
import static org.junit.jupiter.api.Assertions.assertEquals;
10+
11+
import java.util.List;
12+
import org.junit.jupiter.api.Test;
13+
14+
/**
15+
* Basic tests for ThreadedBinaryTree inorder traversal.
16+
*/
17+
public class ThreadedBinaryTreeTest {
18+
19+
@Test
20+
public void testInorderTraversalSimple() {
21+
ThreadedBinaryTree tree = new ThreadedBinaryTree();
22+
tree.insert(50);
23+
tree.insert(30);
24+
tree.insert(70);
25+
tree.insert(20);
26+
tree.insert(40);
27+
tree.insert(60);
28+
tree.insert(80);
29+
30+
List<Integer> expected = List.of(20, 30, 40, 50, 60, 70, 80);
31+
List<Integer> actual = tree.inorderTraversal();
32+
33+
assertEquals(expected, actual);
34+
}
35+
36+
@Test
37+
public void testInorderWithDuplicates() {
38+
ThreadedBinaryTree tree = new ThreadedBinaryTree();
39+
tree.insert(5);
40+
tree.insert(3);
41+
tree.insert(7);
42+
tree.insert(7); // duplicate
43+
tree.insert(2);
44+
45+
List<Integer> expected = List.of(2, 3, 5, 7, 7);
46+
List<Integer> actual = tree.inorderTraversal();
47+
48+
assertEquals(expected, actual);
49+
}
50+
}

0 commit comments

Comments
 (0)