<repo_name>UQuark0/ADS-Labs<file_sep>/src/me/uquark/univ/ads/labs/lab7/Tree.java
package me.uquark.univ.ads.labs.lab7;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class Tree<T> {
    public static class Optional<K> {
        public final boolean isEmpty;
        public final K value;
        public static final Optional empty = new Optional(null, true);

        public Optional(K value, boolean isEmpty) {
            this.value = value;
            this.isEmpty = isEmpty;
        }

        public Optional(K value) {
            this(value, false);
        }
    }

    public interface Searcher<T> {
        boolean accepts(T value);
    }

    public T value;
    public Tree<T> left, right;

    public Tree(T value) {
        this.value = value;
    }

    public void add(T value) {
        if (this.value == null) {
            this.value = value;
            return;
        }

        if (left == null) {
            left = new Tree<>(value);
            return;
        }
        if (right == null) {
            right = new Tree<>(value);
            return;
        }

        if (left.getNodesCount(false) <= right.getNodesCount(false))
            left.add(value);
        else
            right.add(value);
    }

    public static Tree fromArray(Object... array) {
        if (array.length == 0)
            return null;
        Tree tree = new Tree(array[0]);
        for (int i=1; i < array.length; i++)
            tree.add(array[i]);
        return tree;
    }

    public Optional<Tree<T>> delete(T value) {
        if (this.value.equals(value)) {
            delete(left, right);
            if (left != null)
                return new Optional<>(left);
            if (right != null)
                return new Optional<>(right);
            return new Optional<>(null);
        }

        Optional<Tree<T>> newTree;

        if (left != null) {
            newTree = left.delete(value);
            if (!newTree.isEmpty) {
                left = newTree.value;
                return Optional.empty;
            }
        } else {
            if (right != null) {
                newTree = right.delete(value);
                if (!newTree.isEmpty) {
                    right = newTree.value;
                    return Optional.empty;
                }
            }
            return Optional.empty;
        }

        if (right != null) {
            newTree = right.delete(value);
            if (!newTree.isEmpty) {
                right = newTree.value;
                return Optional.empty;
            }
        }

        return Optional.empty;
    }

    public void delete(Tree<T> newLeft, Tree<T> newRight) {
        if (left != null) {
            left.delete(null, right);
        } else if (right != null) {
            right.delete(left, null);
        }
        if (newLeft != null)
            left = newLeft;
        if (newRight != null)
            right = newRight;
    }

    public int getNodesCount(boolean root) {
        int nodes = 0;
        if (root)
            nodes = 1;
        if (left != null)
            nodes += left.getNodesCount(false) + 1;
        if (right != null)
            nodes += right.getNodesCount(false) + 1;
        return nodes;
    }

    public List<Tree<T>> getNodes(boolean root) {
        List<Tree<T>> list = new ArrayList<>();
        if (root)
            list.add(this);
        list.add(left);
        list.add(right);
        if (left != null) {
            list.addAll(left.getNodes(false));
        }
        if (right != null) {
            list.addAll(right.getNodes(false));
        }
        return list;
    }

    public void forEachNode(Consumer<Tree<T>> consumer) {
        List<Tree<T>> nodes = getNodes(true);
        for (Tree<T> node : nodes)
            consumer.accept(node);
    }

    public Tree<T> find(Searcher<T> searcher) {
        if (searcher.accepts(value))
            return this;
        Tree<T> result = null;

        if (left != null)
            result = left.find(searcher);
        if (result != null)
            return result;

        if (right != null)
            result = right.find(searcher);
        return result;
    }

    public List<Tree<T>> findAll(Searcher<T> searcher) {
        List<Tree<T>> result = new ArrayList<>();

        if (searcher.accepts(value))
            result.add(this);

        if (left != null)
            result.addAll(left.findAll(searcher));
        if (right != null)
            result.addAll(right.findAll(searcher));

        return result;
    }
}
<file_sep>/src/me/uquark/univ/ads/labs/Lab6.java
package me.uquark.univ.ads.labs;

import me.uquark.univ.ads.labs.lab4.Task1;

public class Lab6 {
    private static class Queue<T extends Task1.Printable> extends Task1.ForwardLinkedList<T> {
        public void push(T object) {
            addToEnd(object);
        }

        public T pop() {
            if (begin == null)
                return null;
            T result = begin.object;
            begin = begin.next;
            return result;
        }
    }

    private static class PrintableFloat implements Task1.Printable {
        public final float value;

        public PrintableFloat(float value) {
            this.value = value;
        }

        @Override
        public void print() {
            System.out.print(value);
        }
    }

    public static void main(String[] args) {
        Queue<PrintableFloat> queue = new Queue<>();

        queue.push(new PrintableFloat(-2.2f));
        queue.push(new PrintableFloat(2.3f));
        queue.push(new PrintableFloat(2.2f));
        queue.push(new PrintableFloat(5.1f));
        queue.push(new PrintableFloat(6.7f));
        queue.printAll(" ");

        System.out.println();

        queue.pop();
        queue.pop();
        queue.pop();

        queue.push(new PrintableFloat(1.9f));
        queue.printAll(" ");
    }
}

/*
Контрольні запитання
    1. Що таке черга?
    2. Опишіть порядок роботи з чергою.
    3. Які ви знаєте операції над чергами?
    4. Що таке стек?
    5. Опишіть порядок роботи зі стеком.

    1. Очередь - это структура данных, реализующая модель FIFO (First In, First Out)
    2. В очередь можно добавлять элементы (push) и удалять элементы (pop)
    3. См. п. 2
    4. Стек - это структура данных, реализующая модель LIFO (Last In, First Out)
    5. В стек можно добалять элементы (push) и удалять элементы (pop)
 */<file_sep>/README.md
# ADS-Labs

## <NAME>.
### Вариант 2
Ответы на контрольные вопросы находятся в .java файлах как комментарии.<file_sep>/src/me/uquark/univ/ads/labs/lab4/Task1.java
package me.uquark.univ.ads.labs.lab4;

public class Task1 {
    public interface Printable {
        void print();
    }

    public static class Element<T> {
        public final T object;
        public Element<T> next, previous;

        public Element(T object) {
            this.object = object;
        }
    }

    public static class ForwardLinkedList<T extends Printable> {
        public interface Searcher<K> {
            boolean compare(K object);
        }

        public Element<T> begin = null, end = null;

        public void addToEnd(T object) {
            if (begin == null || end == null) {
                begin = new Element<>(object);
                end = begin;
                return;
            }

            Element<T> newElement = new Element<>(object);
            newElement.previous = end;
            end.next = newElement;
            end = newElement;
        }

        public void delete(int index) {
            Element<T> current = begin;
            for (int i=0; i < index; i++)
                if (current == null || current.next == null)
                    return;
                else
                    current = current.next;
            current.previous.next = current.next;
            current.next.previous = current.previous;
        }

        public void add(int index, T object) {
            Element<T> current = begin;
            if (current == null) {
                addToEnd(object);
                return;
            }
            for (int i=0; i < index; i++)
                if (current.next == null)
                    return;
                else
                    current = current.next;
            Element<T> newElement = new Element<>(object);
            if (current.next == null)
                addToEnd(object);
            else
                current.next = newElement;
        }

        public T find(Searcher<T> searcher) {
            Element<T> current = begin;
            while (current != null) {
                if (searcher.compare(current.object))
                    return current.object;
                current = current.next;
            }
            return null;
        }

        public void printAll(String separator) {
            Element<T> current = begin;
            while (current != null) {
                current.object.print();
                System.out.print(separator);
                current = current.next;
            }
        }

        public int getCount() {
            int counter = 0;
            Element<T> current = begin;
            while (current != null) {
                counter++;
                current = current.next;
            }
            return counter;
        }
    }

    public static class LoopedForwardLinkedList<T extends Printable> extends ForwardLinkedList<T> {
        @Override
        public void addToEnd(T object) {
            super.addToEnd(object);
            end.next = begin;
        }

        @Override
        public void printAll(String separator) {
            Element<T> current = begin;
            while (current != null) {
                current.object.print();
                System.out.print(separator);
                current = current.next;
                if (current == begin)
                    break;
            }
        }

        @Override
        public T find(Searcher<T> searcher) {
            Element<T> current = begin;
            while (current != null) {
                if (searcher.compare(current.object))
                    return current.object;
                current = current.next;
                if (current == begin)
                    break;
            }
            return null;
        }

        @Override
        public int getCount() {
            int counter = 0;
            Element<T> current = begin;
            while (current != null) {
                counter++;
                current = current.next;
                if (current == begin)
                    break;
            }
            return counter;
        }
    }
}
<file_sep>/LICENSE.md

Copyright (C) 2020 <NAME>
