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

org.openforis.commons.collection.Tree Maven / Gradle / Ivy

package org.openforis.commons.collection;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Stack;

/**
 * 
 * @author S. Ricci
 *
 * @param 
 */
public class Tree {
	
	private Node root;
	private Map> itemToNode;
	
	public enum TraversalType {
		BFS, DFS
	}
	
	public Tree() {
		this(null);
	}
	
	public Tree(T rootItem) {
		this.itemToNode = new HashMap>();
		this.root = createNode(rootItem);
		itemToNode.put(rootItem, this.root);
	}

	public Node getRoot() {
		return root;
	}
	
	public Node findNodeByItem(T item) {
		return itemToNode.get(item);
	}
	
	public void reparent(Node node, Node newParent) {
		node.parent.removeChild(node);
		newParent.addChild(node);
	}
	
	public List getItems() {
		final List result = new ArrayList();
		traverse(new NodeVisitor() {
			@Override
			public void visit(Node node) {
				T item = node.item;
				if ( item != null ) {
					result.add(item);
				}
			}
		}, TraversalType.BFS);
		return result;
	}
	
	public void traverse(NodeVisitor visitor) {
		traverse(visitor, TraversalType.DFS);
	}
	
	public void traverse(NodeVisitor visitor, TraversalType traversalType) {
		switch (traversalType) {
		case BFS:
			bfsTraverse(visitor);
			break;
		default:
			dfsTraverse(visitor);
			break;
		}
	}
	
	protected void dfsTraverse(NodeVisitor visitor) {
		Stack> stack = new Stack>();
		stack.push(root);
		while ( ! stack.isEmpty() ) {
			Node node = stack.pop();
			visitor.visit(node);
			stack.addAll(node.children);
		}
	}

	protected void bfsTraverse(NodeVisitor visitor) {
		Queue> queue = new LinkedList>();
		queue.add(this.root);
		while ( ! queue.isEmpty() ) {
			Node node = queue.poll();
			visitor.visit(node);
			queue.addAll(node.getChildren());
		}
	}
	
	public Node createNode(T item) {
		return new Node(this, item);
	}

	public static interface NodeVisitor {
		
		void visit(Node node);
		
	}
	
	public static class Node {
		
		private Tree tree;
		private Node parent;
		private T item;
		private List> children;
		
		private Node(Tree tree) {
			this.tree = tree;
			this.children = new ArrayList>();
		}
		
		private Node(Tree tree, T item) {
			this(tree);
			this.item = item;
		}
		
		public void addChild(Node node) {
			children.add(node);
			node.parent = this;
			tree.itemToNode.put(node.item, node);
		}
		
		public void removeChild(Node node) {
			children.remove(node);
			node.parent = null;
			tree.itemToNode.remove(node.item);
		}
		
		public List> getChildren() {
			return CollectionUtils.unmodifiableList(children);
		}
		
		public int getDepth() {
			Node currentParent = parent;
			int result = 0;
			while ( currentParent != null ) {
				result ++;
				currentParent = currentParent.parent;
			}
			return result;
		}
		
		public boolean isDetached() {
			return parent == null;
		}
		
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy