com.github.andyshao.data.structure.Bitree Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Gear Show documentation
Show all versions of Gear Show documentation
Enhance and formating the coding of JDK
The newest version!
package com.github.andyshao.data.structure;
import com.github.andyshao.data.structure.Bitree.BitreeNode;
import com.github.andyshao.lang.Cleanable;
import java.io.Serial;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
*
* Title: Binary tree
* Descript:
* Copyright: Copryright(c) Feb 11, 2015
* Encoding:UNIX UTF-8
*
* @author Andy.Shao
*
* @param data
*/
public interface Bitree extends Cleanable , Tree> {
/**
* Binary tree node
* @param data type
*/
public interface BitreeNode extends TreeNode{
/**
* Build the default binary tree node
* @return {@link BitreeNode}
* @param data type
*/
public static BitreeNode defaultBitreeNode() {
return new BitreeNode() {
private D data;
private BitreeNode left;
private BitreeNode right;
private BitreeNode parent;
@Override
public D data() {
return this.data;
}
@Override
public void data(D data) {
this.data = data;
}
@Override
public BitreeNode left() {
return this.left;
}
@Override
public void left(BitreeNode left) {
this.left = left;
}
@Override
public BitreeNode right() {
return this.right;
}
@Override
public void right(BitreeNode right) {
this.right = right;
}
@Override
public BitreeNode parent() {
return this.parent;
}
@Override
public void parent(BitreeNode parent) {
this.parent = parent;
}
};
}
/**
* Get data
* @return the data
*/
public DATA data();
/**
* Set data
* @param data the data
*/
public void data(DATA data);
/**
* Get left Node
* @return {@link BitreeNode}
*/
public BitreeNode left();
/**
* Set the left node
* @param left {@link BitreeNode}
*/
public void left(BitreeNode left);
/**
* Get right node
* @return {@link BitreeNode}
*/
public BitreeNode right();
/**
* Set right node
* @param right {@link BitreeNode}
*/
public void right(BitreeNode right);
/**
* The parent node
* @return {@link BitreeNode}
*/
public BitreeNode parent();
/**
* Set parent node
* @param parent {@link BitreeNode}
*/
public void parent(BitreeNode parent);
}
/**
* The criteria binary tree
* @param data type
*/
public class MyBitree implements Bitree {
@Serial
private static final long serialVersionUID = -509145251435765498L;
/**root node*/
protected BitreeNode root;
/**size of the tree*/
protected int size;
/**{@link BitreeNode} factory*/
protected final Supplier> treeNodeFactory;
/**
* build the default binary tree
* @param treeNodeFactory {@link BitreeNode}
*/
public MyBitree(Supplier> treeNodeFactory) {
this.treeNodeFactory = treeNodeFactory;
}
/**
* Build default binary tree
* @param treeNodeFactory {@link BitreeNode}
* @param left {@link Bitree}
* @param right {@link Bitree}
* @param data the data
*/
public MyBitree(Supplier> treeNodeFactory , Bitree left , Bitree right , DATA data) {
this.treeNodeFactory = treeNodeFactory;
this.insLeft(null , data);
//Merge the two binary trees into a single binary tree.
this.root.left(left.root());
this.root.right(right.root());
//Adjust the size of the new binary tree.
this.size = this.size + left.size() + right.size();
}
@Override
public Bitree bitreeMeger(Bitree left , Bitree right , DATA data) {
return new MyBitree(this.getTreeNodeFactory() , left , right , data);
}
@Override
public void clear() {
this.root = null;
this.size = 0;
}
@Override
public Supplier> getTreeNodeFactory() {
return this.treeNodeFactory;
}
@Override
public BitreeNode insLeft(BitreeNode node , DATA data) throws TreeOperationException {
BitreeNode new_node;
//Determine where to insert the node.
if (node == null) {
//Allow insertion at the root only in an empty tree.
if (this.size > 0) throw new TreeOperationException("node is null & the size of tree bigger than 0.");
} else //Normally allow insertion only at the end of a branch.
if (node.left() != null) throw new TreeChildNodeNotEmptyException("the left of node's is not empty");
//Allocate storage for the node.
new_node = this.treeNodeFactory.get();
//Insert the node into the tree.
new_node.data(data);
new_node.left(null);
new_node.right(null);
if (node == null) this.root = new_node;
else {
node.left(new_node);
new_node.parent(node);
}
//Adjust the size of the tree to account for the inserted node.
this.size++;
return new_node;
}
@Override
public BitreeNode insRight(BitreeNode node , DATA data) {
BitreeNode new_node;
if (node == null) {
if (this.size > 0) throw new TreeOperationException("node is null & the size of tree bigger than 0.");
} else if (node.right() != null) throw new TreeChildNodeNotEmptyException("the right child of node's is not null");
//Allocate storage for the node.
new_node = this.treeNodeFactory.get();
new_node.data(data);
new_node.left(null);
new_node.right(null);
if (node == null) this.root = new_node;
else {
node.right(new_node);
new_node.parent(node);
}
//Adjust the size of the tree to account for the inserted node.
this.size++;
return new_node;
}
@Override
public void remLeft(BitreeNode node) {
BitreeNode position;
//Do not allow removal from an empty tree.
if (this.size == 0) throw new TreeIsEmptyException();
//Determine where to remove nodes.
if (node == null) position = this.root;
else position = node.left();
if (position != null) {
this.remLeft(position);
this.remRight(position);
if (node == null) this.root = null;
else node.left(null);
position.parent(null);
}
//Adjust the size of the tree to account for the removed node.
this.size--;
}
@Override
public void remRight(BitreeNode node) {
BitreeNode position;
//Do not allow removal from an empty tree.
if (this.size == 0) throw new TreeIsEmptyException();
//Determine where to remove nodes.
if (node == null) position = this.root;
else position = node.right();
//Remove the nodes.
if (position != null) {
this.remLeft(position.left());
this.remRight(position.right());
if (node == null) this.root = null;
else node.right(null);
position.parent(null);
}
//Adjust the size of the tree to account for the removed node.
this.size--;
}
@Override
public BitreeNode root() {
return this.root;
}
@Override
public int size() {
return this.size;
}
@Override
public void root(BitreeNode node) {
this.root = node;
final AtomicInteger numberOfTree = new AtomicInteger();
Bitree.postorder(this.root , n -> numberOfTree.incrementAndGet());
this.size = numberOfTree.intValue();
}
}
/**
* Get default binary tree
* @return {@link Bitree}
* @param data type
*/
public static Bitree defaultBitTree() {
return Bitree.defaultBitTree(BitreeNode::defaultBitreeNode);
}
/**
* Get default binary tree
* @param treeNodeFactory {@link BitreeNode}
* @return {@link Bitree}
* @param data type
*/
public static Bitree defaultBitTree(Supplier> treeNodeFactory) {
return new Bitree.MyBitree<>(treeNodeFactory);
}
/**
* inorder foreach in {@link Bitree}
* @param node {@link Bitree}
* @param result the result {@link Collection}
* @return {@link Collection}
* @param data type
*/
public static Collection inorder(final BitreeNode node , final Collection result) {
inorder(node , item -> result.add(item.data()));
return result;
}
/**
* inorder foreach the {@link Bitree}
* @param node {@link Bitree}
* @param consumer the consumer of the tree node
* @param data type
*/
public static void inorder(final BitreeNode node, Consumer> consumer) {
//Load the list with an inorder listing of the tree.
if (!Bitree.isEob(node)) {
if (!Bitree.isEob(node.left())) Bitree.inorder(node.left() , consumer);
consumer.accept(node);
if (!Bitree.isEob(node.right())) Bitree.inorder(node.right() , consumer);
}
}
/**
* is Eob
* @param node {@link BitreeNode}
* @return true, if it is Eob
* @param data type
*/
public static boolean isEob(BitreeNode node) {
return node == null;
}
/**
* is leaf
* @param node {@link BitreeNode}
* @return true, if it is leaf
* @param data type
*/
public static boolean isLeaf(BitreeNode node) {
return node.left() == null && node.right() == null;
}
/**
* post order foreach the {@link Bitree}
* @param node {@link Bitree}
* @param result the search sequence {@link Collection}
* @return {@link Collection}
* @param data type
*/
public static Collection postorder(final BitreeNode node , final Collection result) {
postorder(node , item -> result.add(item.data()));
return result;
}
/**
* post order foreach the {@link Bitree}
* @param node {@link Bitree}
* @param consumer the consumer of the {@link Bitree} node
* @param data type
*/
public static void postorder(final BitreeNode node , Consumer> consumer) {
if (!Bitree.isEob(node)) {
if (!Bitree.isEob(node.left())) Bitree.postorder(node.left() , consumer);
if (!Bitree.isEob(node.right())) Bitree.postorder(node.right() , consumer);
consumer.accept(node);
}
}
/**
* preorder foreach the {@link Bitree}
* @param node {@link Bitree}
* @param result the foreach sequence {@link Collection}
* @return {@link Collection}
* @param data type
*/
public static Collection preorder(final BitreeNode node , final Collection result) {
preorder(node , item -> result.add(item.data()));
return result;
}
/**
* preorder foreach the {@link Bitree}
* @param node {@link Bitree}
* @param consumer the consumer of the {@link Bitree} node
* @param data type
*/
public static void preorder(BitreeNode node , Consumer> consumer) {
if (!Bitree.isEob(node)) {
consumer.accept(node);
if (!Bitree.isEob(node.left())) Bitree.preorder(node.left() , consumer);
if (!Bitree.isEob(node.right())) Bitree.preorder(node.right() , consumer);
}
}
/**
* merge two {@link Bitree}s
* @param left the left tree
* @param right the right tree
* @param data the root position data
* @return new {@link Bitree}
*/
public Bitree bitreeMeger(Bitree left , Bitree right , D data);
@Override
public default void clear() {
//Remove all the nodes from the tree.
this.remLeft(null);
}
/**
* Get tree node factory
* @return {@link BitreeNode}
*/
public Supplier> getTreeNodeFactory();
/**
* add a left for node
* if node is null, input a new data for root of tree's.
*
* @param node bit tree node
* @param data data
* @return the left child of node's
* @throws TreeChildNodeNotEmptyException if the left of node's is not
* empty.
* @throws TreeOperationException others operation exception of the action's
*/
public BitreeNode insLeft(BitreeNode node , D data) throws TreeOperationException;
/**
* add a right child for node
* if node is null, input a new data for root of tree's.
*
* @param node bit tree node
* @param data data
* @return the right child of nod's
* @throws TreeChildNodeNotEmptyException if the right child of node's is
* not empty.
* @throws TreeOperationException other operation exception of the action's
*/
public BitreeNode insRight(BitreeNode node , D data) throws TreeOperationException;
/**
* remove the left child of node's.
*
* @param node bit tree node
* @throws TreeIsEmptyException if the tree is empty
* @throws TreeOperationException others exception of action'
*/
public void remLeft(BitreeNode node) throws TreeOperationException;
/**
* remove the right child of node's.
*
* @param node bit tree node
* @throws TreeIsEmptyException if the tree is empty
* @throws TreeOperationException other exception of action'
*/
public void remRight(BitreeNode node) throws TreeOperationException;
@Override
public BitreeNode root();
@Override
public int size();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy