mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-12-19 07:00:35 +08:00
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
This commit is contained in:
committed by
GitHub
parent
ac6fef19dc
commit
14c0b0844e
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user