btns = new ArrayList<>();
+
+ /**
+ * Sukuriama parametrų lentelė (GridBag išdėstymo dėsnis)
+ *
+ * |-------------------------------|
+ * | |------------| |
+ * | lblTexts[0] | tfTexts[0] | |
+ * | |------------| |
+ * | |
+ * | |------------| |
+ * | lblTexts[1] | tfTexts[1] | |
+ * | |------------| |
+ * | ... ... |
+ * |-------------------------------|
+ *
+ *
+ * @param lblTexts
+ * @param tfTexts
+ * @param columnWidth
+ */
+ public Panels(String[] lblTexts, String[] tfTexts, int columnWidth) {
+ super();
+ if (lblTexts == null || tfTexts == null) {
+ throw new IllegalArgumentException("Arguments for table of parameters are incorrect");
+ }
+
+ if (lblTexts.length > tfTexts.length) {
+ tfTexts = Arrays.copyOf(tfTexts, lblTexts.length);
+ Arrays.fill(tfTexts, "");
+ }
+
+ initTableOfParameters(columnWidth, lblTexts, tfTexts);
+ }
+
+ /**
+ * Sukuriamas mygtukų tinklelis (GridLayout išdėstymo dėsnis)
+ *
+ * |-------------------------------------|
+ * | |-------------| |-------------| |
+ * | | btnNames[0] | | btnNames[1] | ... |
+ * | |-------------| |-------------| |
+ * | |
+ * | |-------------| |-------------| |
+ * | | btnNames[2] | | btnNames[3] | ... |
+ * | |-------------| |-------------| |
+ * | ... ... |
+ * |-------------------------------------|
+ *
+ *
+ * @param btnNames
+ * @param gridX
+ * @param gridY
+ */
+ public Panels(String[] btnNames, int gridX, int gridY) {
+ super();
+ if (btnNames == null || gridX < 1 || gridY < 1) {
+ throw new IllegalArgumentException("Arguments for buttons grid are incorrect");
+ }
+ initGridOfButtons(gridX, gridY, btnNames);
+ }
+
+ private void initTableOfParameters(int columnWidth, String[] lblTexts, String[] tfTexts) {
+ setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ // Spacing'as tarp komponentų
+ c.insets = new Insets(SPACING, SPACING, SPACING, SPACING);
+ // Lygiavimas į kairę
+ c.anchor = GridBagConstraints.WEST;
+ // Pasirenkamas pirmas stulpelis..
+ c.gridx = 0;
+ // ..ir į jį sudedami labeliai
+ Arrays.stream(lblTexts).forEach((lblText) -> add(new JLabel(lblText), c));
+ // Pasirenkamas antras stulpelis..
+ c.gridx = 1;
+ // ..ir į jį sudedami textfieldai
+
+ for (String tfText : tfTexts) {
+ JTextField tf = new JTextField(tfText, columnWidth);
+ tf.setHorizontalAlignment(JTextField.CENTER);
+ tf.setBackground(Color.WHITE);
+ tfs.add(tf);
+ add(tf, c);
+ }
+ }
+
+ private void initGridOfButtons(int gridX, int gridY, String[] btnNames) {
+ setLayout(new GridLayout(gridY, gridX, SPACING, SPACING));
+ Queue btnNamesQueue = new LinkedList<>(Arrays.asList(btnNames));
+ for (int i = 0; i < gridX; i++) {
+ for (int j = 0; j < gridY; j++) {
+ if (btnNamesQueue.isEmpty()) {
+ break;
+ }
+ JButton button = new JButton(btnNamesQueue.poll());
+ btns.add(button);
+ add(button);
+ }
+ }
+ }
+
+ /**
+ * Gražinamas parametrų lentelės parametrų sąrašas
+ *
+ * @return Gražinamas parametrų lentelės parametrų sąrašas
+ */
+ public List getParametersOfTable() {
+ return tfs.stream().map(JTextComponent::getText).collect(Collectors.toList());
+ }
+
+ /**
+ * Gražinamas parametrų lentelės JTextField objektų sąrašas
+ *
+ * @return Gražinamas parametrų lentelės JTextField objektų sąrašas
+ */
+ public List getTfOfTable() {
+ return tfs;
+ }
+
+ /**
+ * Gražinamas mygtukų tinklelio JButton objektų sąrašas
+ *
+ * @return Gražinamas mygtukų tinklelio JButton objektų sąrašas
+ */
+ public List getButtons() {
+ return btns;
+ }
+}
diff --git a/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/gui/ValidationException.java b/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/gui/ValidationException.java
new file mode 100644
index 0000000..6bcb700
--- /dev/null
+++ b/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/gui/ValidationException.java
@@ -0,0 +1,41 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package edu.ktu.ds.lab2.gui;
+
+/**
+ * Nuosava situacija, panaudota dialogo struktūrose įvedamų parametrų
+ * tikrinimui.
+ */
+public class ValidationException extends RuntimeException {
+
+ // Situacijos kodas. Pagal ji programuojama programos reakcija į situaciją
+ private final int code;
+
+ public ValidationException(String text) {
+ // (-1) - susitariama, kad tai neutralus kodas.
+ this(text, -1);
+ }
+
+ public ValidationException(String message, int code) {
+ super(message);
+ if (code < -1) {
+ throw new IllegalArgumentException("Illegal code in Validation Exception: " + code);
+ }
+ this.code = code;
+ }
+
+ public ValidationException(String message, Throwable throwable, int code) {
+ super(message, throwable);
+ if (code < -1) {
+ throw new IllegalArgumentException("Illegal code in MyException: " + code);
+ }
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+}
diff --git a/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/optional1/Main.java b/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/optional1/Main.java
new file mode 100644
index 0000000..e832059
--- /dev/null
+++ b/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/optional1/Main.java
@@ -0,0 +1,41 @@
+package edu.ktu.ds.lab2.optional1;
+
+
+import edu.ktu.ds.lab2.utils.BstSet;
+
+public class Main {
+ public static void main(String[] args) {
+ int k = 2;
+ BstSet set = new BstSet<>();
+ BstSet.BstNode a = set.getRoot();
+ set.add(15);
+ set.add(23);
+ set.add(7);
+ set.add(4);
+ set.add(1);
+ set.add(9);
+ System.out.println(set.toVisualizedString());
+
+ System.out.println(IsBalanced(set.getRoot(), k) != -1);
+ }
+
+ public static int IsBalanced(BstSet.BstNode node, int maxBalance) {
+ if (node.left == null && node.right == null) return 0;
+
+ int leftHeight = -1;
+ int rightHeight = -1;
+ if (node.left != null) {
+ leftHeight = IsBalanced(node.left, maxBalance);
+ if (leftHeight == -1) return -1;
+ }
+ if (node.right != null) {
+ rightHeight = IsBalanced(node.right, maxBalance);
+ if (rightHeight == -1) return -1;
+ }
+
+ if (Math.abs(leftHeight - rightHeight) >= maxBalance) return -1;
+
+ return Math.max(leftHeight, rightHeight) + 1;
+ }
+
+}
diff --git a/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/optional2/Main.java b/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/optional2/Main.java
new file mode 100644
index 0000000..d590b5f
--- /dev/null
+++ b/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/optional2/Main.java
@@ -0,0 +1,86 @@
+package edu.ktu.ds.lab2.optional2;
+
+import edu.ktu.ds.lab2.utils.BstSet;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Stack;
+
+public class Main {
+ public static void main(String[] args) {
+ BstSet set = new BstSet<>();
+ set.add(15);
+ set.add(23);
+ set.add(7);
+ set.add(4);
+ set.add(12);
+ set.add(19);
+ set.add(26);
+ set.add(1);
+ set.add(5);
+ set.add(9);
+ set.add(14);
+ set.add(16);
+ set.add(21);
+ set.add(25);
+ set.add(30);
+ System.out.println(set.toVisualizedString());
+ System.out.println(getInnerValues(set));
+ }
+
+ public static > ArrayList getInnerValues(BstSet set) {
+ HashSet excludedValues = new HashSet<>();
+ excludedValues.addAll(getLeftEdge(set));
+ excludedValues.addAll(getRightEdge(set));
+ excludedValues.addAll(getBottomEdge(set));
+
+ ArrayList innerValues = new ArrayList<>();
+ for (E value : set) {
+ if (!excludedValues.contains(value)) {
+ innerValues.add(value);
+ }
+ }
+ return innerValues;
+ }
+
+ public static > ArrayList getLeftEdge(BstSet set) {
+ ArrayList leftEdge = new ArrayList<>();
+ BstSet.BstNode node = set.getRoot();
+ while (node != null) {
+ leftEdge.add(node.element);
+ node = node.left;
+ }
+ return leftEdge;
+ }
+
+ public static > ArrayList getRightEdge(BstSet set) {
+ ArrayList rightEdge = new ArrayList<>();
+ BstSet.BstNode node = set.getRoot();
+ while (node != null) {
+ rightEdge.add(node.element);
+ node = node.right;
+ }
+ return rightEdge;
+ }
+
+ public static > ArrayList getBottomEdge(BstSet set) {
+ ArrayList bottomEdge = new ArrayList<>();
+ Stack> stack = new Stack<>();
+ stack.add(set.getRoot());
+ while (!stack.isEmpty()) {
+ BstSet.BstNode node = stack.pop();
+ if (node.left == null && node.right == null) {
+ bottomEdge.add(node.element);
+ } else {
+ if (node.left != null) {
+ stack.push(node.left);
+ }
+ if (node.right != null) {
+ stack.push(node.right);
+ }
+ }
+ }
+ return bottomEdge;
+ }
+
+}
diff --git a/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/utils/AvlSet.java b/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/utils/AvlSet.java
new file mode 100644
index 0000000..24aebf7
--- /dev/null
+++ b/Lab2_AibesMedziai/src/main/java/edu/ktu/ds/lab2/utils/AvlSet.java
@@ -0,0 +1,236 @@
+package edu.ktu.ds.lab2.utils;
+
+import java.util.Comparator;
+
+/**
+ * Rikiuojamos objektų kolekcijos - aibės realizacija AVL-medžiu.
+ *
+ * @param Aibės elemento tipas. Turi tenkinti interfeisą Comparable, arba
+ * per klasės konstruktorių turi būti paduodamas Comparator
+ * interfeisą tenkinantis objektas.
+ * @author darius.matulis@ktu.lt
+ * @užduotis Peržiūrėkite ir išsiaiškinkite pateiktus metodus.
+ */
+public class AvlSet> extends BstSet implements SortedSet {
+
+ public AvlSet() {
+ }
+
+ public AvlSet(Comparator super E> c) {
+ super(c);
+ }
+
+ /**
+ * Aibė papildoma nauju elementu.
+ *
+ * @param element
+ */
+ @Override
+ public void add(E element) {
+ if (element == null) {
+ throw new IllegalArgumentException("Element is null in add(E element)");
+ }
+ root = addRecursive(element, (AVLNode) root);
+ }
+
+ /**
+ * Privatus rekursinis metodas naudojamas add metode;
+ *
+ * @param element
+ * @param node
+ * @return
+ */
+ private AVLNode addRecursive(E element, AVLNode node) {
+ if (node == null) {
+ size++;
+ return new AVLNode<>(element);
+ }
+ int cmp = c.compare(element, node.element);
+
+ if (cmp < 0) {
+ node.left = addRecursive(element, (AVLNode) node.left);
+ } else if (cmp > 0) {
+ node.right = addRecursive(element, (AVLNode) node.right);
+ }
+
+ if (cmp != 0) {
+ int balance = getBalance(node);
+ if (balance >= 2) {
+ int cmp2 = c.compare(element, node.left.element);
+ node = (cmp2 < 0) ? rightRotation(node) : doubleRightRotation(node);
+ } else if (balance <= -2) {
+ int cmp2 = c.compare(node.right.element, element);
+ node = (cmp2 < 0) ? leftRotation(node) : doubleLeftRotation(node);
+ }
+ }
+
+ node.updateHeight();
+ return node;
+ }
+
+ /**
+ * Pašalinamas elementas iš aibės.
+ *
+ * @param element
+ */
+ @Override
+ public void remove(E element) {
+ if (element == null) {
+ throw new IllegalArgumentException("Element is null in remove(E element)");
+ }
+ root = removeRecursive(element, (AVLNode) root);
+ }
+
+ private int getBalance(AVLNode node) {
+ if (node == null) return 0;
+ return height((AVLNode) node.left) - height((AVLNode) node.right);
+ }
+
+ private AVLNode removeRecursive(E element, AVLNode node) {
+ if (node == null) return null;
+
+ int cmp = c.compare(element, node.element);
+
+ if (cmp < 0) {
+ node.left = removeRecursive(element, (AVLNode) node.left);
+ } else if (cmp > 0) {
+ node.right = removeRecursive(element, (AVLNode) node.right);
+ } else {
+ size--;
+ if (node.left == null && node.right == null) {
+ node = null;
+ } else if (node.left != null && node.right != null) {
+ if (node.right.left != null) {
+ BstNode minimumParent = node;
+ BstNode minimumNode = node.right;
+
+ while (minimumNode.left != null) {
+ minimumParent = minimumNode;
+ minimumNode = minimumNode.left;
+ }
+
+ minimumParent.left = minimumNode.right;
+ node.element = minimumNode.element;
+ } else {
+ node.element = node.right.element;
+ node.right = node.right.right;
+ }
+ } else if (node.left != null) {
+ node = (AVLNode) node.left;
+ } else { // if (node.right != null)
+ node = (AVLNode) node.right;
+ }
+ }
+
+ if (node != null) {
+ node.updateHeight();
+ if (cmp != 0) {
+ int balance = getBalance(node);
+ if (balance >= 2) {
+ int hl = node.left.left != null ? ((AVLNode) node.left.left).height : -1;
+ int hr = node.left.right != null ? ((AVLNode) node.left.right).height : -1;
+ node = (hl >= hr) ? rightRotation(node) : doubleRightRotation(node);
+ } else if (balance <= -2) {
+ int hl = node.right.left != null ? ((AVLNode) node.right.left).height : -1;
+ int hr = node.right.right != null ? ((AVLNode) node.right.right).height : -1;
+ node = (hr >= hl) ? leftRotation(node) : doubleLeftRotation(node);
+ }
+ }
+ }
+
+ return node;
+ }
+
+ // Papildomi privatūs metodai, naudojami operacijų su aibe realizacijai
+ // AVL-medžiu;
+
+ // n2
+ // / n1
+ // n1 ==> / \
+ // / n3 n2
+ // n3
+
+ private AVLNode rightRotation(AVLNode n2) {
+ AVLNode n1 = (AVLNode) n2.left;
+ n2.left = n1.right;
+ n1.right = n2;
+ n2.updateHeight();
+ n1.updateHeight();
+ return n1;
+ }
+
+ private AVLNode leftRotation(AVLNode n1) {
+ AVLNode n2 = (AVLNode) n1.right;
+ n1.right = n2.left;
+ n2.left = n1;
+ n1.updateHeight();
+ n2.updateHeight();
+ return n2;
+ }
+
+ // n3 n3
+ // / / n2
+ // n1 ==> n2 ==> / \
+ // \ / n1 n3
+ // n2 n1
+ //
+ private AVLNode doubleRightRotation(AVLNode n3) {
+ n3.left = leftRotation((AVLNode) n3.left);
+ return rightRotation(n3);
+ }
+
+ private AVLNode doubleLeftRotation(AVLNode n1) {
+ n1.right = rightRotation((AVLNode) n1.right);
+ return leftRotation(n1);
+ }
+
+ public String serialize() {
+ return serialize((AVLNode) root);
+ }
+
+ private String serialize(AVLNode node) {
+ StringBuilder builder = new StringBuilder();
+ if (node.left == null && node.right == null) {
+ builder.append(node.element);
+ } else {
+ builder.append("(");
+ if (node.left != null) {
+ builder.append(serialize((AVLNode) node.left));
+ } else {
+ builder.append("null");
+ }
+ builder.append(",");
+ builder.append(node.element);
+ builder.append(",");
+ if (node.right != null) {
+ builder.append(serialize((AVLNode) node.right));
+ } else {
+ builder.append("null");
+ }
+ builder.append(")");
+ }
+ return builder.toString();
+ }
+
+ private int height(AVLNode n) {
+ return (n == null) ? -1 : n.height;
+ }
+
+ /**
+ * Vidinė kolekcijos mazgo klasė
+ *
+ * @param mazgo elemento duomenų tipas
+ */
+ protected class AVLNode extends BstNode