diff --git a/Java4L6HW/src/alexrm84/Main.java b/Java4L6HW/src/alexrm84/Main.java new file mode 100644 index 0000000..0f3ce75 --- /dev/null +++ b/Java4L6HW/src/alexrm84/Main.java @@ -0,0 +1,52 @@ +package alexrm84; + +public class Main { + + public static void main(String[] args) { +// Tree tree = new TreeImplement<>(); +// tree.add(60); +// tree.add(25); +// tree.add(66); +// tree.add(15); +// tree.add(5); +// tree.add(20); +// tree.add(45); +// tree.add(30); +// tree.add(32); +// tree.add(55); +// +// tree.display(); +// +// System.out.println("Find 60: " + tree.find(60)); +// System.out.println("Find 45: " + tree.find(45)); +// System.out.println("Find 32: " + tree.find(32)); +// System.out.println("Find 666: " + tree.find(666)); +// +// tree.remove(15); +// tree.display(); + + int balancedNodes=0; + + for (int i = 0; i < 100; i++) { + Tree tree = new TreeImplement<>(); + for (int j = 0; j < 15; j++) { + tree.add((int) (Math.random()*200)-100); + } + if (isBalanced(((TreeImplement) tree).getRootNode())){ + balancedNodes++; + } + } + System.out.println("Percentage of balanced trees: " + balancedNodes + "%"); + } + + public static boolean isBalanced(Node node) { + return (node == null) || + isBalanced(node.getLeftChild()) && + isBalanced(node.getRightChild()) && + Math.abs(height(node.getLeftChild()) - height(node.getRightChild())) <= 1; + } + + private static int height(Node node) { + return node == null ? 0 : 1 + Math.max(height(node.getLeftChild()), height(node.getRightChild())); + } +} diff --git a/Java4L6HW/src/alexrm84/Node.java b/Java4L6HW/src/alexrm84/Node.java new file mode 100644 index 0000000..ce743c5 --- /dev/null +++ b/Java4L6HW/src/alexrm84/Node.java @@ -0,0 +1,73 @@ +package alexrm84; + +import java.util.Objects; + +public class Node> { + + private final E value; + + private int level; + + private Node leftChild; + private Node rightChild; + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public Node(E value) { + this.value = value; + } + + public E getValue() { + return value; + } + + public Node getLeftChild() { + return leftChild; + } + + public void setLeftChild(Node leftChild) { + this.leftChild = leftChild; + } + + public Node getRightChild() { + return rightChild; + } + + public void setRightChild(Node rightChild) { + this.rightChild = rightChild; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Node node = (Node) o; + return Objects.equals(value, node.value); + } + + public boolean shouldLeftChild(E value){ + if (value.compareTo(getValue())<0){ + return true; + }else { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return "Node{" + + "value=" + value + + '}'; + } +} diff --git a/Java4L6HW/src/alexrm84/Tree.java b/Java4L6HW/src/alexrm84/Tree.java new file mode 100644 index 0000000..0a3cc72 --- /dev/null +++ b/Java4L6HW/src/alexrm84/Tree.java @@ -0,0 +1,22 @@ +package alexrm84; + +public interface Tree> { + + enum TraversMode { + IN_ORDER, + PRE_ORDER, + POST_ORDER + } + + void add(E value); + + boolean remove(E value); + + boolean find(E value); + + void display(); + + boolean isEmpty(); + + void travers(TraversMode traversMode); +} diff --git a/Java4L6HW/src/alexrm84/TreeImplement.java b/Java4L6HW/src/alexrm84/TreeImplement.java new file mode 100644 index 0000000..49904ff --- /dev/null +++ b/Java4L6HW/src/alexrm84/TreeImplement.java @@ -0,0 +1,228 @@ +package alexrm84; + +import javafx.scene.layout.Priority; + +import java.util.Stack; + +public class TreeImplement> implements Tree { + + private Node rootNode; + + public Node getRootNode() { + return rootNode; + } + + @Override + public void add(E value) { + Node newNode = new Node<>(value); + if (isEmpty()){ + rootNode=newNode; + rootNode.setLevel(0); + return; + } + Node current = rootNode; + int currentLVL = 0; + Node previous = null; + while (current!=null){ + previous=current; + currentLVL++; + if (current.getValue().equals(value) || currentLVL==4){ + return; + } + if (current.shouldLeftChild(value)){ + current=current.getLeftChild(); + }else { + current=current.getRightChild(); + } + } + if (previous.shouldLeftChild(value)){ + previous.setLeftChild(newNode); + newNode.setLevel(currentLVL); + }else { + previous.setRightChild(newNode); + newNode.setLevel(currentLVL); + } + + } + + @Override + public boolean remove(E value) { + Node current = rootNode; + Node parent = null; + while (current!=null){ + if (current.getValue().equals(value)){ + break; + } + parent=current; + if (current.shouldLeftChild(value)){ + current=current.getLeftChild(); + }else { + current=current.getRightChild(); + } + } + if (current==null){ + return false; + } + if (isLeaf(current)){ + if (current==rootNode){ + rootNode=null; + }else if (parent.getLeftChild().equals(current)){ + parent.setLeftChild(null); + }else { + parent.setRightChild(null); + } + }else if (hasOnlySingleChildElement(current)) { + Node childNode = current.getLeftChild() != null + ? current.getLeftChild() + : current.getRightChild(); + if (current==rootNode){ + rootNode=childNode; + }else if (parent.getLeftChild().equals(current)){ + parent.setLeftChild(childNode); + }else { + parent.setRightChild(childNode); + } + }else { + Node successor = getSuccessor(current); + if (current==rootNode){ + rootNode=successor; + }else if (parent.getLeftChild().equals(current)){ + parent.setLeftChild(successor); + }else { + parent.setRightChild(successor); + } + successor.setLeftChild(current.getLeftChild()); + } + return true; + } + + private Node getSuccessor(Node removeNode){ + Node successor=removeNode; + Node successorParent= null; + Node curent = removeNode.getRightChild(); + while (curent!=null){ + successorParent=successor; + successor=curent; + curent=curent.getLeftChild(); + } + if (successor!=removeNode.getRightChild()){ + successorParent.setLeftChild(successor.getRightChild()); + successor.setRightChild(removeNode.getRightChild()); + } + return successor; + } + + private boolean hasOnlySingleChildElement(Node current){ + return current.getLeftChild()==null || current.getRightChild()==null; + } + + private boolean isLeaf(Node current){ + return current.getLeftChild()==null && current.getRightChild()==null; + } + + @Override + public boolean find(E value) { + Node current = rootNode; + while (current!=null){ + if (current.getValue().equals(value)){ + return true; + } + if (current.shouldLeftChild(value)){ + current=current.getLeftChild(); + }else { + current=current.getRightChild(); + } + } + return false; + } + + @Override + public void display() { + Stack globalStack = new Stack<>(); + globalStack.push(rootNode); + int nBlanks=64; + boolean isRowEmpty=false; + System.out.println("--------------------------------------------------------------"); + while (!isRowEmpty){ + Stack localStack = new Stack<>(); + isRowEmpty=true; + for (int i = 0; i < nBlanks; i++) { + System.out.print(" "); + } + + while (!globalStack.isEmpty()){ + Node tempNode = globalStack.pop(); + if (tempNode!=null){ + System.out.print(tempNode.getValue()); + localStack.push(tempNode.getLeftChild()); + localStack.push(tempNode.getRightChild()); + if (tempNode.getLeftChild()!=null || tempNode.getRightChild()!=null){ + isRowEmpty=false; + } + }else { + System.out.print("--"); + localStack.push(null); + localStack.push(null); + } + for (int i = 0; i < nBlanks*2-2; i++) { + System.out.print(" "); + } + } + System.out.println(); + while (!localStack.isEmpty()){ + globalStack.push(localStack.pop()); + } + nBlanks/=2; + } + System.out.println("--------------------------------------------------------------"); + } + + @Override + public boolean isEmpty() { + return rootNode==null; + } + + @Override + public void travers(TraversMode traversMode) { + switch (traversMode){ + case IN_ORDER: + inOrder(rootNode); + break; + case PRE_ORDER: + preOrder(rootNode); + break; + case POST_ORDER: + postOrder(rootNode); + break; + default: + throw new IllegalArgumentException("Unknown traverse mode " + traversMode); + } + } + + private void inOrder(Node node){ + if (node==null){ + return; + } + inOrder(node.getLeftChild()); + System.out.println(node); + inOrder(node.getRightChild()); + } + + private void preOrder(Node node){ + if (node==null){ + return; + } + System.out.println(node); + inOrder(node.getLeftChild()); + inOrder(node.getRightChild()); + } + + private void postOrder(Node node){ + if (node==null){ + return; + } + inOrder(node.getLeftChild()); + inOrder(node.getRightChild()); + System.out.println(node); + } +}