Skip to content

Commit

Permalink
Дерево
Browse files Browse the repository at this point in the history
  • Loading branch information
Pastor committed Dec 5, 2024
1 parent 794fb15 commit 756d838
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 7 deletions.
26 changes: 26 additions & 0 deletions vol6/src/main/java/ru/mifi/practice/vol6/tree/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package ru.mifi.practice.vol6.tree;

import ru.mifi.practice.vol6.tree.visitors.OnSubTree;

import java.io.IOException;
import java.util.Comparator;

public abstract class Main {
public static void main(String[] args) throws IOException {
Tree<Integer> tree = new ParserText<Integer>().parse(Main.class.getResourceAsStream("/standard.tree"),
Integer::parseInt, Comparator.comparing(k -> k));
System.out.print("PRE : ");
tree.visit(new Visitor.Stdout<>(), new VisitorStrategy.PreOrder<>());
System.out.println();
System.out.print("POST: ");
tree.visit(new Visitor.Stdout<>(), new VisitorStrategy.PostOrder<>());
System.out.println();
System.out.print("IN : ");
tree.visit(new Visitor.Stdout<>(), new VisitorStrategy.InOrder<>());
System.out.println();
OnSubTree<Integer> on = new OnSubTree<>();
tree.visit(on, new VisitorStrategy.PreOrder<>());
System.out.println(on);
System.out.println(tree);
}
}
11 changes: 11 additions & 0 deletions vol6/src/main/java/ru/mifi/practice/vol6/tree/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public Node<T> left() {

@Override
public Node<T> left(T value) {
if (value == null) {
return left;
}
return left = new Default<>(this, value);
}

Expand All @@ -59,6 +62,9 @@ public Node<T> right() {

@Override
public Node<T> right(T value) {
if (value == null) {
return right;
}
return right = new Default<>(this, value);
}

Expand All @@ -80,5 +86,10 @@ public Node<T> deleteRight(T value) {
public void visit(Visitor<T> visitor, VisitorStrategy<T> strategy) {
strategy.visit(this, visitor, strategy);
}

@Override
public String toString() {
return "(" + value + ")";
}
}
}
48 changes: 48 additions & 0 deletions vol6/src/main/java/ru/mifi/practice/vol6/tree/ParserText.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package ru.mifi.practice.vol6.tree;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.function.Function;

@SuppressWarnings({"PMD.EmptyControlStatement", "PMD.CompareObjectsWithEquals"})
public final class ParserText<T> implements Tree.Loader<T> {

public Tree<T> parse(String text, Function<String, T> value, Comparator<T> comparator) throws IOException {
return parse(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)), value, comparator);
}

@Override
public Tree<T> parse(InputStream stream, Function<String, T> value, Comparator<T> comparator) throws IOException {
Tree.Standard<T> tree = new Tree.Standard<>(comparator);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.isEmpty()) {
continue;
}
String[] parts = line.split(":");
String owner = parts[0].trim();
String left = "";
String right = "";
String description = parts[1].trim();
if (description.isEmpty()) {
continue;
} else if (description.charAt(0) == '{' && description.charAt(description.length() - 1) == '}') {
description = description.substring(1, description.length() - 1);
parts = description.split(",");
left = parts[0].trim();
right = parts[1].trim();
}
tree.add(value.apply(owner),
left.isEmpty() ? null : value.apply(left), right.isEmpty() ? null : value.apply(right));
}
}
return tree;
}
}
57 changes: 57 additions & 0 deletions vol6/src/main/java/ru/mifi/practice/vol6/tree/Tree.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package ru.mifi.practice.vol6.tree;

import java.io.IOException;
import java.io.InputStream;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.function.Function;

public interface Tree<T> extends Visitor.Visit<T> {

Expand All @@ -9,6 +14,10 @@ public interface Tree<T> extends Visitor.Visit<T> {
@Override
void visit(Visitor<T> visitor, VisitorStrategy<T> strategy);

interface Loader<T> {
Tree<T> parse(InputStream stream, Function<String, T> value, Comparator<T> comparator) throws IOException;
}

abstract class AbstractTree<T> implements Tree<T> {
protected final Comparator<T> comparator;
protected Node<T> root;
Expand All @@ -33,4 +42,52 @@ public void visit(Visitor<T> visitor, VisitorStrategy<T> strategy) {
}
}
}

final class Standard<T> extends AbstractTree<T> implements Tree<T> {
public Standard(Comparator<T> comparator) {
super(comparator);
}

@Override
Node<T> add(Node<T> root, T element) {
return null;
}

public void add(T owner, T left, T right) {
if (root == null) {
root = Node.root(owner);
root.left(left);
root.right(right);
} else {
Node<T> find = search(root, owner);
if (find == null) {
throw new IllegalArgumentException("No such element: " + owner);
}
find.left(left);
find.right(right);
}
}

private Node<T> search(Node<T> root, T element) {
if (root != null) {
Queue<Node<T>> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
Node<T> node = queue.poll();
if (node.value() != null && node.value().equals(element)) {
return node;
}
if (node.left() != null) {
queue.add(node.left());
}
if (node.right() != null) {
queue.add(node.right());
}
}
}
return null;
}

;
}
}
14 changes: 10 additions & 4 deletions vol6/src/main/java/ru/mifi/practice/vol6/tree/Visitor.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package ru.mifi.practice.vol6.tree;

public interface Visitor<T> {
void visit(Node<T> node);
void enterNode(Node<T> node);
void exitNode(Node<T> node);

void empty();

Expand All @@ -13,13 +14,18 @@ interface Visit<T> {
final class Stdout<T> implements Visitor<T> {

@Override
public void visit(Node<T> node) {
System.out.println(node);
public void enterNode(Node<T> node) {
System.out.print(node);
}

@Override
public void exitNode(Node<T> node) {

}

@Override
public void empty() {
System.out.println("empty");
System.out.print("empty");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ public void visit(Node<T> node, Visitor<T> visitor, VisitorStrategy<T> strategy)
if (node == null) {
return;
}
visitor.visit(node);
visitor.enterNode(node);
strategy.visit(node.left(), visitor, strategy);
strategy.visit(node.right(), visitor, strategy);
visitor.exitNode(node);
}
}

Expand All @@ -24,7 +25,8 @@ public void visit(Node<T> node, Visitor<T> visitor, VisitorStrategy<T> strategy)
}
strategy.visit(node.left(), visitor, strategy);
strategy.visit(node.right(), visitor, strategy);
visitor.visit(node);
visitor.enterNode(node);
visitor.exitNode(node);
}
}

Expand All @@ -35,8 +37,9 @@ public void visit(Node<T> node, Visitor<T> visitor, VisitorStrategy<T> strategy)
return;
}
strategy.visit(node.left(), visitor, strategy);
visitor.visit(node);
visitor.enterNode(node);
strategy.visit(node.right(), visitor, strategy);
visitor.exitNode(node);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package ru.mifi.practice.vol6.tree.visitors;

import ru.mifi.practice.vol6.tree.Node;
import ru.mifi.practice.vol6.tree.Visitor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public final class OnSubTree<T> implements Visitor<T> {
private final Map<Node<T>, Integer> stepsIn = new HashMap<>();
private final Map<Node<T>, Integer> stepsOut = new HashMap<>();
private final AtomicInteger steps = new AtomicInteger();

void clear() {
stepsIn.clear();
stepsOut.clear();
steps.set(0);
}

@Override
public void enterNode(Node<T> node) {
if (node != null) {
int step = steps.incrementAndGet();
stepsIn.put(node, step);
}
}

@Override
public void exitNode(Node<T> node) {
if (node != null) {
stepsOut.put(node, steps.incrementAndGet());
}
}

@SuppressWarnings("checked")
public List<Node<T>> times() {
List<Node<T>> result = new ArrayList<>();
Node[] nodes = new Node[stepsIn.size() * 2 + 1];
for (var key : stepsIn.keySet()) {
int in = stepsIn.get(key);
int out = stepsOut.get(key);
nodes[in] = key;
nodes[out] = key;
}
for (Node node : nodes) {
if (node == null) {
continue;
}
result.add(node);
}
return result;
}


@Override
public void empty() {

}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
StringBuilder fl = new StringBuilder();
StringBuilder sl = new StringBuilder();
List<Node<T>> times = times();
for (int i = 0; i < times.size(); i++) {
Node<T> node = times.get(i);
fl.append(String.format("%2d ", i));
sl.append(String.format("%2s ", node.value()));
}
sb.append(fl).append("\n").append(sl);
return sb.toString();
}
}
6 changes: 6 additions & 0 deletions vol6/src/main/resources/standard.tree
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
1:{ 2, 3}
3:{ 4, 5}
4:{ 9, }
9:{11, 10}
5:{ 6, 7}
7:{ 8, }

0 comments on commit 756d838

Please sign in to comment.