162 lines
6.2 KiB
Java
162 lines
6.2 KiB
Java
import java.io.PrintStream;
|
|
import java.util.Random;
|
|
import java.util.concurrent.Callable;
|
|
|
|
/**
|
|
* Eine Sammlung von Klassenmethoden, um wiederkehrende
|
|
* Aufgaben mit binären Bäumen zu vereinfachen.
|
|
* @version 0.1 (2019-09-13)
|
|
* @author J. Neugebauer <schule@neugebauer.cc>
|
|
*/
|
|
public class Trees {
|
|
|
|
public static <T> int getMaxDepth( BinaryTree<T> pRoot ) {
|
|
if( pRoot.isEmpty() ) {
|
|
return 0;
|
|
}
|
|
return 1 + Math.max(
|
|
getMaxDepth( pRoot.getLeftTree() ),
|
|
getMaxDepth( pRoot.getRightTree() )
|
|
);
|
|
}
|
|
|
|
public static <T> int countNodes( BinaryTree<T> pRoot ) {
|
|
if( pRoot.isEmpty() ) {
|
|
return 0;
|
|
}
|
|
return 1 + countNodes( pRoot.getLeftTree() ) + countNodes( pRoot.getRightTree() );
|
|
}
|
|
|
|
public static <T> int countLeaves( BinaryTree<T> pRoot ) {
|
|
if( pRoot.isEmpty() ) {
|
|
return 0;
|
|
} else if( pRoot.getLeftTree().isEmpty() && pRoot.getRightTree().isEmpty() ) {
|
|
return 1;
|
|
}
|
|
return countLeaves( pRoot.getLeftTree() ) + countLeaves( pRoot.getRightTree() );
|
|
}
|
|
|
|
public static <T> void printPretty( BinaryTree<T> pRoot ) {
|
|
printPretty(pRoot, System.out);
|
|
}
|
|
|
|
public static <T> void printPretty( BinaryTree<T> pRoot, PrintStream pOut ) {
|
|
pOut.print(printPretty(pRoot, new StringBuilder(), true, new StringBuilder()).toString());
|
|
}
|
|
|
|
// Adapted from https://stackoverflow.com/a/27153988/10921408
|
|
private static <T> StringBuilder printPretty( BinaryTree<T> pRoot, StringBuilder prefix, boolean isTail, StringBuilder sb) {
|
|
if( !pRoot.getRightTree().isEmpty() ) {
|
|
printPretty(pRoot.getRightTree(), new StringBuilder().append(prefix).append(isTail ? "│ " : " "), false, sb);
|
|
}
|
|
sb.append(prefix).append(isTail ? "└── " : "┌── ").append(pRoot.getContent().toString()).append("\n");
|
|
if( !pRoot.getLeftTree().isEmpty() ) {
|
|
printPretty(pRoot.getLeftTree(), new StringBuilder().append(prefix).append(isTail ? " " : "│ "), true, sb);
|
|
}
|
|
return sb;
|
|
}
|
|
|
|
public static <T> void printPreorder( BinaryTree<T> pRoot ) {
|
|
printPreorder(pRoot, System.out);
|
|
}
|
|
|
|
public static <T> void printPreorder( BinaryTree<T> pRoot, PrintStream pOut ) {
|
|
if( pRoot.getContent() == null ) {
|
|
return;
|
|
}
|
|
|
|
pOut.print(pRoot.getContent().toString() + ",");
|
|
printPreorder(pRoot.getLeftTree(), pOut);
|
|
printPreorder(pRoot.getRightTree(), pOut);
|
|
}
|
|
|
|
public static <T> void printPostorder( BinaryTree<T> pRoot ) {
|
|
printPostorder(pRoot, System.out);
|
|
}
|
|
|
|
public static <T> void printPostorder( BinaryTree<T> pRoot, PrintStream pOut ) {
|
|
if( pRoot.getContent() == null ) {
|
|
return;
|
|
}
|
|
|
|
pOut.print(pRoot.getContent().toString() + ",");
|
|
printPostorder(pRoot.getLeftTree(), pOut);
|
|
printPostorder(pRoot.getRightTree(), pOut);
|
|
}
|
|
|
|
public static <T> void printInorder( BinaryTree<T> pRoot ) {
|
|
printInorder(pRoot, System.out);
|
|
}
|
|
|
|
public static <T> void printInorder( BinaryTree<T> pRoot, PrintStream pOut ) {
|
|
if( pRoot.getContent() == null ) {
|
|
return;
|
|
}
|
|
|
|
pOut.print(pRoot.getContent().toString() + ",");
|
|
printInorder(pRoot.getLeftTree(), pOut);
|
|
printInorder(pRoot.getRightTree(), pOut);
|
|
}
|
|
|
|
public static BinaryTree<Integer> generateBalancedIntegerTree( int pNodeCount, int pMinValue, int pMaxValue ) {
|
|
return generateIntegerTree(pNodeCount, pMinValue, pMaxValue, 0.5, 0.0);
|
|
}
|
|
|
|
public static BinaryTree<Integer> generateCompleteIntegerTree( int pDepth, int pMinValue, int pMaxValue ) {
|
|
return generateBalancedIntegerTree((int)Math.pow(2,pDepth)-1, pMinValue, pMaxValue);
|
|
}
|
|
|
|
public static BinaryTree<Integer> generateIntegerTree( int pNodeCount, double pWeight, double pUncertainty ) {
|
|
return generateIntegerTree(pNodeCount, 0, 100, pWeight, pUncertainty);
|
|
}
|
|
|
|
public static BinaryTree<Integer> generateIntegerTree( int pNodeCount, int pMinValue, int pMaxValue, double pWeight, double pUncertainty ) {
|
|
final Random rand = new Random();
|
|
return generateTree(pNodeCount, new Callable<Integer>() {
|
|
@Override
|
|
public Integer call() throws Exception {
|
|
return new Integer(rand.nextInt(pMaxValue-pMinValue)+pMinValue);
|
|
}
|
|
}, pWeight, pUncertainty);
|
|
}
|
|
|
|
public static BinaryTree<String> generateStringTree( int pNodeCount, double pWeight, double pUncertainty ) {
|
|
return generateStringTree(pNodeCount, new String[]{"Jonas", "Martin", "Harald", "Sabine", "Feline", "Kathrin"}, pWeight, pUncertainty);
|
|
}
|
|
|
|
public static BinaryTree<String> generateStringTree( int pNodeCount, final String[] pWords, double pWeight, double pUncertainty ) {
|
|
final Random rand = new Random();
|
|
return generateTree(pNodeCount, new Callable<String>() {
|
|
@Override
|
|
public String call() throws Exception {
|
|
return pWords[rand.nextInt(pWords.length)];
|
|
}
|
|
}, pWeight, pUncertainty);
|
|
}
|
|
|
|
public static <T> BinaryTree<T> generateTree( int pNodeCount, Callable<T> pGenerator, double pWeight, double pUncertainty ) {
|
|
return generateTree(new BinaryTree<T>(), pNodeCount, pGenerator, pWeight, pUncertainty);
|
|
}
|
|
|
|
public static <T> BinaryTree<T> generateTree( BinaryTree<T> pRoot, int pNodeCount, Callable<T> pGenerator, double pWeight, double pUncertainty ) {
|
|
if( pNodeCount > 0 ) {
|
|
try {
|
|
pRoot.setContent(pGenerator.call());
|
|
} catch( Exception ex ) {
|
|
return pRoot;
|
|
}
|
|
|
|
|
|
double weight = pWeight + (pUncertainty - (Math.random() * pUncertainty * 2));
|
|
weight = Math.min(1.0, Math.max(0.0, weight));
|
|
int leftCount = (int) (pNodeCount * weight);
|
|
int rightCount = pNodeCount - leftCount - 1;
|
|
|
|
generateTree(pRoot.getLeftTree(), leftCount, pGenerator, pWeight, pUncertainty);
|
|
generateTree(pRoot.getRightTree(), rightCount, pGenerator, pWeight, pUncertainty);
|
|
}
|
|
return pRoot;
|
|
}
|
|
|
|
}
|