org.deephacks.tools4j.config.test.validation.BinaryTreeUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tools4j-config-tck Show documentation
Show all versions of tools4j-config-tck Show documentation
Functional Tests for Tools4j Config
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.deephacks.tools4j.config.test.validation;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.deephacks.tools4j.config.model.Bean;
import org.deephacks.tools4j.config.model.Bean.BeanId;
public class BinaryTreeUtils {
public static Set getTree(Integer root, List children) {
Node rootNode = new Node(root);
for (int i : children) {
rootNode.insert(i);
}
Set beans = new HashSet();
rootNode.traverse(beans, null);
return beans;
}
public static Bean getBean(int i, Set beans) {
for (Bean bean : beans) {
if (new Integer(bean.getId().getInstanceId()).intValue() == i) {
return bean;
}
}
return null;
}
public static class Node {
int value = 0;
public Node left;
public Node right;
Node(int value) {
this.value = value;
}
public Bean traverse(Set beans, Bean parent) {
Bean current = Bean.create(BeanId.create(value + "", "binarytree"));
current.setProperty("value", value + "");
if (parent != null) {
current.setReference("parent", parent.getId());
}
if (left != null) {
Bean leftBean = left.traverse(beans, current);
current.setReference("left", leftBean.getId());
}
if (right != null) {
Bean rightBean = right.traverse(beans, current);
current.setReference("right", rightBean.getId());
}
beans.add(current);
return current;
}
public void insert(int insert) {
if (value == insert) {
return;
}
if (value > insert) {
if (left != null) {
left.insert(insert);
} else {
left = new Node(insert);
}
} else {
if (right != null) {
right.insert(insert);
} else {
right = new Node(insert);
}
}
}
public Node delete(int delete) {
if (value == delete) {
if (left != null && right != null) {
Node x = right;
while (x.left != null) {
x = x.left;
}
value = x.value;
x.value = delete;
right = right.delete(delete);
return this;
} else if (left != null) {
return left;
} else if (right != null) {
return right;
} else {
return null;
}
} else if (value > delete) {
left = (left == null) ? null : left.delete(delete);
return this;
} else {
right = (right == null) ? null : right.delete(delete);
return this;
}
}
public String toString() {
return value + "";
}
}
public static void printPretty(BinaryTree root) {
TreePrinter.printPretty(root, 1, 0, new TreePrinter.PaddedWriter(System.out));
}
private static class TreePrinter {
// Search for the deepest part of the tree
private static int maxHeight(BinaryTree t) {
if (t == null)
return 0;
int leftHeight = maxHeight(t.getLeft());
int rightHeight = maxHeight(t.getRight());
return (leftHeight > rightHeight) ? leftHeight + 1 : rightHeight + 1;
}
// Pretty formatting of a binary tree to the output stream
public static void printPretty(BinaryTree tree, int level, int indentSpace,
PaddedWriter out) {
int h = maxHeight(tree);
int BinaryTreesInThisLevel = 1;
int branchLen = 2 * ((int) Math.pow(2.0, h) - 1) - (3 - level)
* (int) Math.pow(2.0, h - 1);
int BinaryTreeSpaceLen = 2 + (level + 1) * (int) Math.pow(2.0, h);
int startLen = branchLen + (3 - level) + indentSpace;
Deque BinaryTreesQueue = new LinkedList();
BinaryTreesQueue.offerLast(tree);
for (int r = 1; r < h; r++) {
printBranches(branchLen, BinaryTreeSpaceLen, startLen, BinaryTreesInThisLevel,
BinaryTreesQueue, out);
branchLen = branchLen / 2 - 1;
BinaryTreeSpaceLen = BinaryTreeSpaceLen / 2 + 1;
startLen = branchLen + (3 - level) + indentSpace;
printBinaryTrees(branchLen, BinaryTreeSpaceLen, startLen, BinaryTreesInThisLevel,
BinaryTreesQueue, out);
for (int i = 0; i < BinaryTreesInThisLevel; i++) {
BinaryTree currBinaryTree = BinaryTreesQueue.pollFirst();
if (currBinaryTree != null) {
BinaryTreesQueue.offerLast(currBinaryTree.getLeft());
BinaryTreesQueue.offerLast(currBinaryTree.getRight());
} else {
BinaryTreesQueue.offerLast(null);
BinaryTreesQueue.offerLast(null);
}
}
BinaryTreesInThisLevel *= 2;
}
printBranches(branchLen, BinaryTreeSpaceLen, startLen, BinaryTreesInThisLevel,
BinaryTreesQueue, out);
printLeaves(indentSpace, level, BinaryTreesInThisLevel, BinaryTreesQueue, out);
}
private static void printBranches(int branchLen, int BinaryTreeSpaceLen, int startLen,
int BinaryTreesInThisLevel, Deque BinaryTreesQueue, PaddedWriter out) {
Iterator iterator = BinaryTreesQueue.iterator();
for (int i = 0; i < BinaryTreesInThisLevel / 2; i++) {
if (i == 0) {
out.setw(startLen - 1);
} else {
out.setw(BinaryTreeSpaceLen - 2);
}
out.write();
BinaryTree next = iterator.next();
if (next != null) {
out.write("/");
} else {
out.write(" ");
}
out.setw(2 * branchLen + 2);
out.write();
next = iterator.next();
if (next != null) {
out.write("\\");
} else {
out.write(" ");
}
}
out.endl();
}
// Print the branches and BinaryTree (eg, ___10___ )
private static void printBinaryTrees(int branchLen, int BinaryTreeSpaceLen,
int startLen, int BinaryTreesInThisLevel, Deque BinaryTreesQueue,
PaddedWriter out) {
Iterator iterator = BinaryTreesQueue.iterator();
BinaryTree currentBinaryTree;
for (int i = 0; i < BinaryTreesInThisLevel; i++) {
currentBinaryTree = iterator.next();
if (i == 0) {
out.setw(startLen);
} else {
out.setw(BinaryTreeSpaceLen);
}
out.write();
if (currentBinaryTree != null && currentBinaryTree.getLeft() != null) {
out.setfill('_');
} else {
out.setfill(' ');
}
out.setw(branchLen + 2);
if (currentBinaryTree != null) {
out.write(currentBinaryTree.toString());
} else {
out.write();
}
if (currentBinaryTree != null && currentBinaryTree.getRight() != null) {
out.setfill('_');
} else {
out.setfill(' ');
}
out.setw(branchLen);
out.write();
out.setfill(' ');
}
out.endl();
}
// Print the leaves only (just for the bottom row)
private static void printLeaves(int indentSpace, int level, int BinaryTreesInThisLevel,
Deque BinaryTreesQueue, PaddedWriter out) {
Iterator iterator = BinaryTreesQueue.iterator();
BinaryTree currentBinaryTree;
for (int i = 0; i < BinaryTreesInThisLevel; i++) {
currentBinaryTree = iterator.next();
if (i == 0) {
out.setw(indentSpace + 2);
} else {
out.setw(2 * level + 2);
}
if (currentBinaryTree != null) {
out.write(currentBinaryTree.toString());
} else {
out.write();
}
}
out.endl();
}
public static class PaddedWriter {
private int width = 0;
private char fillChar = ' ';
private final PrintStream writer;
public PaddedWriter(PrintStream writer) {
this.writer = writer;
}
void setw(int i) {
width = i;
}
void setfill(char c) {
fillChar = c;
}
void write(String str) {
write(str.toCharArray());
}
void write(char[] buf) {
if (buf.length < width) {
char[] pad = new char[width - buf.length];
Arrays.fill(pad, fillChar);
writer.print(pad);
}
writer.print(buf);
setw(0);
}
void write() {
char[] pad = new char[width];
Arrays.fill(pad, fillChar);
writer.print(pad);
setw(0);
}
void endl() {
writer.println();
setw(0);
}
}
}
}