Minor changes + reformatting

This commit is contained in:
Abhinav Sarkar 2019-08-09 15:31:44 +05:30
parent a68a6522c2
commit 6048270224

View File

@ -8,101 +8,101 @@ import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
class TreeIerators { class TreeIerators {
public static void main(String[] args) { public static void main(String[] args) {
Tree<String> tree; Tree<String> tree;
do { do {
tree = Tree.generate(4, () -> Utils.generateRandomAlphaString(2), 0.1); tree = Tree.generate(4, () -> Utils.generateRandomAlphaString(2), 0.1);
} while (tree == null); } while (tree == null);
System.out.println("Tree:"); System.out.println("Tree:");
System.out.println(tree); System.out.println(tree);
// InOrderIterator // InOrderIterator
InOrderIterator.printRecursive(tree); InOrderIterator.printRecursive(tree);
System.out.println("\tInOrderIterator.printRecursive"); System.out.println("\tInOrderIterator.printRecursive");
InOrderIterator.iterateRecursive(tree, Utils::printContent); InOrderIterator.iterateRecursive(tree, Utils::printContent);
System.out.println("\tInOrderIterator.iterateRecursive"); System.out.println("\tInOrderIterator.iterateRecursive");
InOrderIterator.iterateCPS(tree, Utils::printContent, () -> {}); InOrderIterator.iterateCPS(tree, Utils::printContent, () -> {});
System.out.println("\tInOrderIterator.iterateCPS"); System.out.println("\tInOrderIterator.iterateCPS");
InOrderIterator.iterateDefCPS(tree, Utils::printContent, null); InOrderIterator.iterateDefCPS(tree, Utils::printContent, null);
System.out.println("\tInOrderIterator.iterateDefCPS"); System.out.println("\tInOrderIterator.iterateDefCPS");
InOrderIterator.iterate(tree, Utils::printContent, null); InOrderIterator.iterate(tree, Utils::printContent, null);
System.out.println("\tInOrderIterator.iterate"); System.out.println("\tInOrderIterator.iterate");
InOrderIterator<String> inOrderIterator = new InOrderIterator<>(tree); InOrderIterator<String> inOrderIterator = new InOrderIterator<>(tree);
while (inOrderIterator.hasNext()) { while (inOrderIterator.hasNext()) {
Utils.printContent(inOrderIterator.next()); Utils.printContent(inOrderIterator.next());
}
System.out.println("\tInOrderIterator");
System.out.println();
// PreOrderIterator
PreOrderIterator.printRecursive(tree);
System.out.println("\tPreOrderIterator.printRecursive");
PreOrderIterator.iterateRecursive(tree, Utils::printContent);
System.out.println("\tPreOrderIterator.iterateRecursive");
PreOrderIterator.iterateCPS(tree, Utils::printContent, () -> {});
System.out.println("\tPreOrderIterator.iterateCPS");
PreOrderIterator.iterateDefCPS(tree, Utils::printContent, null);
System.out.println("\tPreOrderIterator.iterateDefCPS");
PreOrderIterator.iterate(tree, Utils::printContent, null);
System.out.println("\tPreOrderIterator.iterate");
PreOrderIterator<String> preOrderIterator = new PreOrderIterator<>(tree);
while (preOrderIterator.hasNext()) {
Utils.printContent(preOrderIterator.next());
}
System.out.println("\tPreOrderIterator");
System.out.println();
// PostOrderIterator
PostOrderIterator.printRecursive(tree);
System.out.println("\tPostOrderIterator.printRecursive");
PostOrderIterator.iterateRecursive(tree, Utils::printContent);
System.out.println("\tPostOrderIterator.iterateRecursive");
PostOrderIterator.iterateCPS(tree, Utils::printContent, () -> {});
System.out.println("\tPostOrderIterator.iterateCPS");
PostOrderIterator.iterateDefCPS(tree, Utils::printContent, null);
System.out.println("\tPostOrderIterator.iterateDefCPS");
PostOrderIterator.iterate(tree, Utils::printContent, null);
System.out.println("\tPostOrderIterator.iterate");
PostOrderIterator<String> postOrderIterator = new PostOrderIterator<>(tree);
while (postOrderIterator.hasNext()) {
Utils.printContent(postOrderIterator.next());
}
System.out.println("\tPostOrderIterator");
} }
System.out.println("\tInOrderIterator");
System.out.println();
// PreOrderIterator
PreOrderIterator.printRecursive(tree);
System.out.println("\tPreOrderIterator.printRecursive");
PreOrderIterator.iterateRecursive(tree, Utils::printContent);
System.out.println("\tPreOrderIterator.iterateRecursive");
PreOrderIterator.iterateCPS(tree, Utils::printContent, () -> {});
System.out.println("\tPreOrderIterator.iterateCPS");
PreOrderIterator.iterateDefCPS(tree, Utils::printContent, null);
System.out.println("\tPreOrderIterator.iterateDefCPS");
PreOrderIterator.iterate(tree, Utils::printContent, null);
System.out.println("\tPreOrderIterator.iterate");
PreOrderIterator<String> preOrderIterator = new PreOrderIterator<>(tree);
while (preOrderIterator.hasNext()) {
Utils.printContent(preOrderIterator.next());
}
System.out.println("\tPreOrderIterator");
System.out.println();
// PostOrderIterator
PostOrderIterator.printRecursive(tree);
System.out.println("\tPostOrderIterator.printRecursive");
PostOrderIterator.iterateRecursive(tree, Utils::printContent);
System.out.println("\tPostOrderIterator.iterateRecursive");
PostOrderIterator.iterateCPS(tree, Utils::printContent, () -> {});
System.out.println("\tPostOrderIterator.iterateCPS");
PostOrderIterator.iterateDefCPS(tree, Utils::printContent, null);
System.out.println("\tPostOrderIterator.iterateDefCPS");
PostOrderIterator.iterate(tree, Utils::printContent, null);
System.out.println("\tPostOrderIterator.iterate");
PostOrderIterator<String> postOrderIterator = new PostOrderIterator<>(tree);
while (postOrderIterator.hasNext()) {
Utils.printContent(postOrderIterator.next());
}
System.out.println("\tPostOrderIterator");
}
/* Run result: /* Run result:
Tree: Tree:
r r
j j
x x
e e
m m
vz vz
g g
<NULL> <NULL>
l l
b b
qc qc
g g
rp rp
d d
o o
e x m j g vz r qc b g l d rp o InOrderIterator.printRecursive e x m j g vz r qc b g l d rp o InOrderIterator.printRecursive
e x m j g vz r qc b g l d rp o InOrderIterator.iterateRecursive e x m j g vz r qc b g l d rp o InOrderIterator.iterateRecursive
@ -128,414 +128,415 @@ class TreeIerators {
} }
class Tree<T> { class Tree<T> {
Tree<T> left; Tree<T> left;
T content; T content;
Tree<T> right; Tree<T> right;
Tree(Tree<T> left, T content, Tree<T> right) { Tree(Tree<T> left, T content, Tree<T> right) {
this.left = left; this.left = left;
this.content = content; this.content = content;
this.right = right; this.right = right;
}
public static <T> Tree<T> generate(int maxDepth, Supplier<T> gen, double nullProbability) {
if (nullProbability < 0 || nullProbability > 1) {
throw new IllegalArgumentException("nullProbability must be between 0 and 1");
} }
public static <T> Tree<T> generate(int maxDepth, Supplier<T> gen, double nullProbability) { if (maxDepth == 0) {
if (nullProbability < 0 || nullProbability > 1) { return null;
throw new IllegalArgumentException("nullProbability must be between 0 and 1");
}
if (maxDepth == 0) {
return null;
}
double rand = ThreadLocalRandom.current().nextDouble();
if (rand < nullProbability) {
return null;
}
Tree<T> left = generate(maxDepth - 1, gen, nullProbability);
Tree<T> right = generate(maxDepth - 1, gen, nullProbability);
return new Tree<>(left, gen.get(), right);
} }
@Override double rand = ThreadLocalRandom.current().nextDouble();
public String toString() { if (rand < nullProbability) {
return toStringLayout(0).toString(); return null;
} }
private StringBuilder toStringLayout(int level) { Tree<T> left = generate(maxDepth - 1, gen, nullProbability);
StringBuilder guidelines = Utils.makeGuidelines(level); Tree<T> right = generate(maxDepth - 1, gen, nullProbability);
StringBuilder sb = new StringBuilder().append(guidelines).append(content).append("\n"); return new Tree<>(left, gen.get(), right);
if (this.left == null && this.right == null) { }
return sb;
}
if (this.left != null) { @Override
sb.append(this.left.toStringLayout(level + 1)); public String toString() {
} else { return toStringLayout(0).toString();
sb.append(guidelines).append("<NULL>\n"); }
}
if (this.right != null) { private StringBuilder toStringLayout(int level) {
sb.append(this.right.toStringLayout(level + 1)); StringBuilder sb = new StringBuilder().append(Utils.makeGuidelines(level)).append(content).append("\n");
} else { if (this.left == null && this.right == null) {
sb.append(guidelines).append("<NULL>\n"); return sb;
}
return sb;
} }
StringBuilder nullChildGuidelines = Utils.makeGuidelines(level + 1);
if (this.left != null) {
sb.append(this.left.toStringLayout(level + 1));
} else {
sb.append(nullChildGuidelines).append("<NULL>\n");
}
if (this.right != null) {
sb.append(this.right.toStringLayout(level + 1));
} else {
sb.append(nullChildGuidelines).append("<NULL>\n");
}
return sb;
}
} }
class InOrderIterator<T> implements Iterator<T> { class InOrderIterator<T> implements Iterator<T> {
private static class Cont<T> { private static class Cont<T> {
final Tree<T> tree; final Tree<T> tree;
final Cont<T> next; final Cont<T> next;
Cont(Tree<T> tree, Cont<T> next) { Cont(Tree<T> tree, Cont<T> next) {
this.tree = tree; this.tree = tree;
this.next = next; this.next = next;
}
} }
}
static <T> void printRecursive(Tree<T> tree) { static <T> void printRecursive(Tree<T> tree) {
if (tree != null) { if (tree != null) {
printRecursive(tree.left); printRecursive(tree.left);
Utils.printContent(tree.content); Utils.printContent(tree.content);
printRecursive(tree.right); printRecursive(tree.right);
}
} }
}
static <T> void iterateRecursive(Tree<T> tree, Consumer<T> action) { static <T> void iterateRecursive(Tree<T> tree, Consumer<T> action) {
if (tree != null) { if (tree != null) {
iterateRecursive(tree.left, action); iterateRecursive(tree.left, action);
action.accept(tree.content); action.accept(tree.content);
iterateRecursive(tree.right, action); iterateRecursive(tree.right, action);
}
} }
}
static <T> void iterateCPS(Tree<T> tree, Consumer<T> action, Runnable cont) { static <T> void iterateCPS(Tree<T> tree, Consumer<T> action, Runnable cont) {
if (tree != null) { if (tree != null) {
iterateCPS(tree.left, action, () -> { iterateCPS(tree.left, action, () -> {
action.accept(tree.content); action.accept(tree.content);
iterateCPS(tree.right, action, cont); iterateCPS(tree.right, action, cont);
}); });
} else {
cont.run();
}
}
static <T> void iterateDefCPS(Tree<T> tree, Consumer<T> action, Cont<T> cont) {
if (tree != null) {
iterateDefCPS(tree.left, action, new Cont<>(tree, cont));
} else {
if (cont != null) {
action.accept(cont.tree.content);
iterateDefCPS(cont.tree.right, action, cont.next);
} else {
return;
}
}
}
static <T> void iterate(Tree<T> tree, Consumer<T> action, Cont<T> cont) {
while (true) {
if (tree != null) {
cont = new Cont<>(tree, cont);
tree = tree.left;
} else {
if (cont != null) {
action.accept(cont.tree.content);
tree = cont.tree.right;
cont = cont.next;
} else { } else {
cont.run(); return;
} }
}
} }
}
static <T> void iterateDefCPS(Tree<T> tree, Consumer<T> action, Cont<T> cont) { private Tree<T> tree;
if (tree != null) { private Stack<Tree<T>> stack = new Stack<>();
iterateDefCPS(tree.left, action, new Cont<>(tree, cont));
} else { InOrderIterator(Tree<T> tree) {
if (cont != null) { this.tree = tree;
action.accept(cont.tree.content); }
iterateDefCPS(cont.tree.right, action, cont.next);
} else { @Override
return; public boolean hasNext() {
} return tree != null || !stack.isEmpty();
}
@Override
public T next() {
while (hasNext()) {
if (tree != null) {
stack.push(tree);
tree = tree.left;
} else {
if (!stack.isEmpty()) {
Tree<T> t = stack.pop();
T content = t.content;
tree = t.right;
return content;
} }
}
} }
throw new NoSuchElementException();
static <T> void iterate(Tree<T> tree, Consumer<T> action, Cont<T> cont) { }
while (true) {
if (tree != null) {
cont = new Cont<>(tree, cont);
tree = tree.left;
} else {
if (cont != null) {
action.accept(cont.tree.content);
tree = cont.tree.right;
cont = cont.next;
} else {
return;
}
}
}
}
private Tree<T> tree;
private Stack<Tree<T>> stack = new Stack<>();
InOrderIterator(Tree<T> tree) {
this.tree = tree;
}
@Override
public boolean hasNext() {
return tree != null || !stack.isEmpty();
}
@Override
public T next() {
while (hasNext()) {
if (tree != null) {
stack.push(tree);
tree = tree.left;
} else {
if (!stack.isEmpty()) {
Tree<T> t = stack.pop();
T content = t.content;
tree = t.right;
return content;
}
}
}
throw new NoSuchElementException();
}
} }
class PreOrderIterator<T> implements Iterator<T> { class PreOrderIterator<T> implements Iterator<T> {
private static class Cont<T> { private static class Cont<T> {
final Tree<T> tree; final Tree<T> tree;
final Cont<T> next; final Cont<T> next;
Cont(Tree<T> tree, Cont<T> next) { Cont(Tree<T> tree, Cont<T> next) {
this.tree = tree; this.tree = tree;
this.next = next; this.next = next;
}
} }
}
static <T> void printRecursive(Tree<T> tree) { static <T> void printRecursive(Tree<T> tree) {
if (tree != null) { if (tree != null) {
Utils.printContent(tree.content); Utils.printContent(tree.content);
printRecursive(tree.left); printRecursive(tree.left);
printRecursive(tree.right); printRecursive(tree.right);
}
} }
}
static <T> void iterateRecursive(Tree<T> tree, Consumer<T> action) { static <T> void iterateRecursive(Tree<T> tree, Consumer<T> action) {
if (tree != null) { if (tree != null) {
action.accept(tree.content); action.accept(tree.content);
iterateRecursive(tree.left, action); iterateRecursive(tree.left, action);
iterateRecursive(tree.right, action); iterateRecursive(tree.right, action);
}
} }
}
static <T> void iterateCPS(Tree<T> tree, Consumer<T> action, Runnable cont) { static <T> void iterateCPS(Tree<T> tree, Consumer<T> action, Runnable cont) {
if (tree != null) { if (tree != null) {
action.accept(tree.content); action.accept(tree.content);
iterateCPS(tree.left, action, () -> iterateCPS(tree.right, action, cont)); iterateCPS(tree.left, action, () -> iterateCPS(tree.right, action, cont));
} else {
cont.run();
}
}
static <T> void iterateDefCPS(Tree<T> tree, Consumer<T> action, Cont<T> cont) {
if (tree != null) {
action.accept(tree.content);
iterateDefCPS(tree.left, action, new Cont<>(tree.right, cont));
} else {
if (cont != null) {
iterateDefCPS(cont.tree, action, cont.next);
} else {
return;
}
}
}
static <T> void iterate(Tree<T> tree, Consumer<T> action, Cont<T> cont) {
while (true) {
if (tree != null) {
action.accept(tree.content);
cont = new Cont<>(tree.right, cont);
tree = tree.left;
} else {
if (cont != null) {
tree = cont.tree;
cont = cont.next;
} else { } else {
cont.run(); return;
} }
}
} }
}
static <T> void iterateDefCPS(Tree<T> tree, Consumer<T> action, Cont<T> cont) { private Tree<T> tree;
if (tree != null) { private Stack<Tree<T>> stack = new Stack<>();
action.accept(tree.content);
iterateDefCPS(tree.left, action, tree.right != null ? new Cont<>(tree.right, cont) : cont); PreOrderIterator(Tree<T> tree) {
} else { this.tree = tree;
if (cont != null) { }
iterateDefCPS(cont.tree, action, cont.next);
} else { @Override
return; public boolean hasNext() {
} return tree != null || !stack.isEmpty();
}
@Override
public T next() {
while (hasNext()) {
if (tree != null) {
T content = tree.content;
if (tree.right != null) {
stack.push(tree.right);
} }
} tree = tree.left;
return content;
static <T> void iterate(Tree<T> tree, Consumer<T> action, Cont<T> cont) { } else {
while (true) { if (!stack.isEmpty()) {
if (tree != null) { tree = stack.pop();
action.accept(tree.content);
if (tree.right != null) {
cont = new Cont<>(tree.right, cont);
}
tree = tree.left;
} else {
if (cont != null) {
tree = cont.tree;
cont = cont.next;
} else {
return;
}
}
} }
}
} }
throw new NoSuchElementException();
private Tree<T> tree; }
private Stack<Tree<T>> stack = new Stack<>();
PreOrderIterator(Tree<T> tree) {
this.tree = tree;
}
@Override
public boolean hasNext() {
return tree != null || !stack.isEmpty();
}
@Override
public T next() {
while (hasNext()) {
if (tree != null) {
T content = tree.content;
if (tree.right != null) {
stack.push(tree.right);
}
tree = tree.left;
return content;
} else {
if (!stack.isEmpty()) {
tree = stack.pop();
}
}
}
throw new NoSuchElementException();
}
} }
class PostOrderIterator<T> implements Iterator<T> { class PostOrderIterator<T> implements Iterator<T> {
static class Cont<T> { static class Cont<T> {
final Tree<T> tree; final Tree<T> tree;
final boolean isRight; final boolean isLeft;
final Cont<T> next; final Cont<T> next;
Cont(Tree<T> tree, boolean isRight, Cont<T> next) { Cont(Tree<T> tree, boolean isLeft, Cont<T> next) {
this.tree = tree; this.tree = tree;
this.next = next; this.next = next;
this.isRight = isRight; this.isLeft = isLeft;
}
} }
}
static <T> void printRecursive(Tree<T> tree) { static <T> void printRecursive(Tree<T> tree) {
if (tree != null) { if (tree != null) {
printRecursive(tree.left); printRecursive(tree.left);
printRecursive(tree.right); printRecursive(tree.right);
Utils.printContent(tree.content); Utils.printContent(tree.content);
}
} }
}
static <T> void iterateRecursive(Tree<T> tree, Consumer<T> action) { static <T> void iterateRecursive(Tree<T> tree, Consumer<T> action) {
if (tree != null) { if (tree != null) {
iterateRecursive(tree.left, action); iterateRecursive(tree.left, action);
iterateRecursive(tree.right, action); iterateRecursive(tree.right, action);
action.accept(tree.content); action.accept(tree.content);
}
} }
}
static <T> void iterateCPS(Tree<T> tree, Consumer<T> action, Runnable cont) { static <T> void iterateCPS(Tree<T> tree, Consumer<T> action, Runnable cont) {
if (tree != null) { if (tree != null) {
iterateCPS(tree.left, action, () -> iterateCPS(tree.right, action, () -> { iterateCPS(tree.left, action, () -> iterateCPS(tree.right, action, () -> {
action.accept(tree.content); action.accept(tree.content);
cont.run(); cont.run();
})); }));
} else {
cont.run();
}
}
static <T> void iterateDefCPS(Tree<T> tree, Consumer<T> action, Cont<T> cont) {
if (tree != null) {
Cont<T> rCont = new Cont<>(tree, false, cont);
Cont<T> lCont = new Cont<>(tree.right, true, rCont);
iterateDefCPS(tree.left, action, lCont);
} else {
if (cont != null) {
if (cont.isLeft) {
iterateDefCPS(cont.tree, action, cont.next);
} else { } else {
cont.run(); action.accept(cont.tree.content);
iterateDefCPS(null, action, cont.next);
} }
} else {
return;
}
} }
}
static <T> void iterate(Tree<T> tree, Consumer<T> action, Cont<T> cont) {
static <T> void iterateDefCPS(Tree<T> tree, Consumer<T> action, Cont<T> cont) { while (true) {
if (tree != null) { if (tree != null) {
cont = new Cont<>(tree, false, cont); cont = new Cont<>(tree, false, cont);
iterateDefCPS(tree.left, action, tree.right != null ? new Cont<>(tree.right, true, cont) : cont); cont = new Cont<>(tree.right, true, cont);
tree = tree.left;
} else {
if (cont != null) {
if (cont.isLeft) {
tree = cont.tree;
} else {
action.accept(cont.tree.content);
tree = null;
}
cont = cont.next;
} else { } else {
if (cont != null) { return;
if (!cont.isRight) {
action.accept(cont.tree.content);
}
iterateDefCPS(cont.isRight ? cont.tree : null, action, cont.next);
} else {
return;
}
} }
}
} }
}
static <T> void iterate(Tree<T> tree, Consumer<T> action, Cont<T> cont) { private static class TreeTup<T> {
while (true) { final Tree<T> tree;
if (tree != null) { final boolean isLeft;
cont = new Cont<>(tree, false, cont);
cont = tree.right != null ? new Cont<>(tree.right, true, cont) : cont; public TreeTup(Tree<T> tree, boolean isLeft) {
tree = tree.left; this.tree = tree;
} else { this.isLeft = isLeft;
if (cont != null) { }
if (!cont.isRight) { }
action.accept(cont.tree.content);
tree = null; private Tree<T> tree;
} else { private Stack<TreeTup<T>> stack = new Stack<>();
tree = cont.tree;
} PostOrderIterator(Tree<T> tree) {
cont = cont.next; this.tree = tree;
} else { }
return;
} @Override
} public boolean hasNext() {
return tree != null || !stack.isEmpty();
}
@Override
public T next() {
while (hasNext()) {
if (tree != null) {
stack.push(new TreeTup<>(tree, false));
if (tree.right != null) {
stack.push(new TreeTup<>(tree.right, true));
} }
} tree = tree.left;
} else {
private static class TreeTup<T> { if (!stack.isEmpty()) {
final Tree<T> tree; TreeTup<T> tup = stack.pop();
final boolean isRight; if (tup.isLeft) {
tree = tup.tree;
public TreeTup(Tree<T> tree, boolean isRight) { } else {
this.tree = tree; T content = tup.tree.content;
this.isRight = isRight; tree = null;
return content;
}
} }
}
} }
throw new NoSuchElementException();
private Tree<T> tree; }
private Stack<TreeTup<T>> stack = new Stack<>();
PostOrderIterator(Tree<T> tree) {
this.tree = tree;
}
@Override
public boolean hasNext() {
return tree != null || !stack.isEmpty();
}
@Override
public T next() {
while (hasNext()) {
if (tree != null) {
stack.push(new TreeTup<>(tree, false));
if (tree.right != null) {
stack.push(new TreeTup<>(tree.right, true));
}
tree = tree.left;
} else {
if (!stack.isEmpty()) {
TreeTup<T> tup = stack.pop();
if (!tup.isRight) {
T content = tup.tree.content;
tree = null;
return content;
} else {
tree = tup.tree;
}
}
}
}
throw new NoSuchElementException();
}
} }
class Utils { class Utils {
static <T> void printContent(T t) { static <T> void printContent(T t) {
System.out.printf(t + " "); System.out.printf(t + " ");
} }
static String generateRandomAlphaString(int maxLength) { static String generateRandomAlphaString(int maxLength) {
ThreadLocalRandom random = ThreadLocalRandom.current(); ThreadLocalRandom random = ThreadLocalRandom.current();
int targetLength = random.nextInt(maxLength) + 1; int targetLength = random.nextInt(maxLength) + 1;
StringBuilder sb = new StringBuilder(targetLength); StringBuilder sb = new StringBuilder(targetLength);
for (int i = 0; i < targetLength; i++) { for (int i = 0; i < targetLength; i++) {
sb.append((char) random.nextInt('a', 'z' + 1)); sb.append((char) random.nextInt('a', 'z' + 1));
}
return sb.toString();
} }
return sb.toString();
}
static StringBuilder makeGuidelines(int times) { static StringBuilder makeGuidelines(int times) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < times; i++) { for (int i = 0; i < times; i++) {
sb.append('│'); sb.append("");
}
return sb.append("");
} }
return sb.append("");
}
} }