All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.andyshao.data.structure.Bitree Maven / Gradle / Ivy

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