Minor changes + reformatting
This commit is contained in:
parent
a68a6522c2
commit
6048270224
@ -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("├ ");
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user