diff --git a/README.md b/README.md new file mode 100644 index 0000000..06283e7 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# AlgorithmsAndDataStructures +Create TreeMap +1. Создать и запустить программу для построения двоичного дерева. +В цикле построить двадцать деревьев с глубиной в 6 уровней. +Данные, которыми необходимо заполнить узлы деревьев, представляются в виде чисел типа int. +Число, которое попадает в узел, должно генерироваться случайным образом в диапазоне от -100 до 100. + +2. Проанализировать, какой процент созданных деревьев являются несбалансированными. diff --git a/src/algorithmsAndDataStructures/Main.java b/src/algorithmsAndDataStructures/Main.java index ba454e2..d0bf500 100644 --- a/src/algorithmsAndDataStructures/Main.java +++ b/src/algorithmsAndDataStructures/Main.java @@ -1,8 +1,26 @@ package algorithmsAndDataStructures; +import java.util.concurrent.ThreadLocalRandom; + public class Main { public static void main(String[] args) { - // write your code here + final int count = 100000; + int isBalance = 0; + + for (int i = 0; i < count; i++) { + MyTreeMap treeMap = new MyTreeMap<>(); + while (treeMap.height() < 6) { + treeMap.put(ThreadLocalRandom.current().nextInt(-100, 100), + ThreadLocalRandom.current().nextInt(0, 100)); + } + System.out.println(treeMap); + + if (treeMap.isBalance()) + isBalance++; + } + System.out.println("Total wood: " + count + + ", balanced wood: " + isBalance + + ", not balanced wood: " + (count - isBalance)); } -} +} \ No newline at end of file diff --git a/src/algorithmsAndDataStructures/MyTreeMap.java b/src/algorithmsAndDataStructures/MyTreeMap.java new file mode 100644 index 0000000..3052b55 --- /dev/null +++ b/src/algorithmsAndDataStructures/MyTreeMap.java @@ -0,0 +1,222 @@ +package algorithmsAndDataStructures; + +import java.util.NoSuchElementException; + +public class MyTreeMap, V> { + private Node root; + + private class Node { + int height; + K key; + V value; + Node left; + Node right; + int size; + + public Node(K key, V value, int size, int height) { + this.key = key; + this.value = value; + this.size = size; + this.height = height; + } + } + + public int size() { + return size(root); + } + + private int size(Node node) { + if (node == null) { + return 0; + } + return node.size; + } + + public boolean isEmpty() { + return root == null; + } + + private void checkKeyNotNull(K key) { + if (key == null) { + throw new IllegalArgumentException("key не должен быть null"); + } + } + + public boolean contains(K key) { + return get(key) != null; + } + + public V get(K key) { + checkKeyNotNull(key); + return get(root, key); + } + + private V get(Node node, K key) { + if (node == null) { + return null; + } + int cmp = key.compareTo(node.key); + if (cmp == 0) { + return node.value; + } else if (cmp < 0) { + return get(node.left, key); + } else { + return get(node.right, key); + } + } + + public void put(K key, V value) { + checkKeyNotNull(key); + if (value == null) { + return; + } + root = put(root, key, value); + } + + private Node put(Node node, K key, V value) { + if (node == null) { + return new Node(key, value, 1, 0); + } + int cmp = key.compareTo(node.key); + if (cmp == 0) { + node.value = value; + } else if (cmp < 0) { + node.left = put(node.left, key, value); + } else { + node.right = put(node.right, key, value); + } + node.size = 1 + size(node.left) + size(node.right); + height(node); + return node; + } + + private Node max(Node node) { + if (node.right == null) { + return node; + } + return max(node.right); + } + + public K maxKey() { + return max(root).key; + } + + + public K minKey() { + return min(root).key; + } + + private Node min(Node node) { + if (node.left == null) { + return node; + } + return min(node.left); + } + + public void deleteMin() { + if (isEmpty()) { + throw new NoSuchElementException(); + } + root = deleteMin(root); + } + + private Node deleteMin(Node node) { + if (node.left == null) { + return node.right; + } + node.left = deleteMin(node.left); + node.size = 1 + size(node.left) + size(node.right); + height(node); + return node; + } + + public void delete(K key) { + checkKeyNotNull(key); + root = delete(root, key); + } + + private Node delete(Node node, K key) { + if (node == null) { + return null; + } + int cmp = key.compareTo(node.key); + if (cmp < 0) { + node.left = delete(node.left, key); + } else if (cmp > 0) { + node.right = delete(node.right, key); + } else { + if (node.left == null) { + return node.right; + } + if (node.right == null) { + return node.left; + } + Node temp = node; + node = min(node.right); + node.right = deleteMin(temp.right); + node.left = temp.left; + } + node.size = 1 + size(node.left) + size(node.right); + height(node); + return node; + } + + public int height() { + return height(root); + } + + private int height(Node node) { + if (node == null) { + return 0; + } + if (node.left == null && node.right == null) { + node.height = 0; + } else if (node.left != null && node.right == null) { + node.height = 1 + node.left.height; + } else if (node.left == null) { + node.height = 1 + node.right.height; + } else if (node.left.height > node.right.height) { + node.height = 1 + node.left.height; + } else if (node.left.height < node.right.height) { + node.height = 1 + node.right.height; + } else { + node.height = 1 + node.left.height; + } + return node.height; + } + + public boolean isBalance() { + if (root == null || root.size == 1) { + return true; + } else { + int heightLeft; + int heightRight; + + if (root.left == null) { + heightLeft = 0; + } else { + heightLeft = root.left.height; + } + + if (root.right == null) { + heightRight = 0; + } else { + heightRight = root.right.height; + } + return Math.abs(heightLeft - heightRight) <= 1; + } + } + + @Override + public String toString() { + return toString(root); + } + + private String toString(Node node) { + if (node == null) { + return ""; + } + return toString(node.left) + "[" + node.key + ", " + node.value + "]" + + toString(node.right); + } +} \ No newline at end of file