From bd363ae662584657f158559b16f0a0d7722185cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Dobrovoljc?= Date: Tue, 17 Dec 2024 16:36:15 +0100 Subject: [PATCH] Izziv 4 --- .../inspectionProfiles/Project_Default.xml | 1 + izzivi/src/izziv4/Izziv4.java | 400 ++++++++++++++++++ izzivi/src/izziv4/rezultati.png | Bin 0 -> 19805 bytes 3 files changed, 401 insertions(+) create mode 100644 izzivi/src/izziv4/Izziv4.java create mode 100644 izzivi/src/izziv4/rezultati.png diff --git a/izzivi/.idea/inspectionProfiles/Project_Default.xml b/izzivi/.idea/inspectionProfiles/Project_Default.xml index 581c216..5f2e5cd 100644 --- a/izzivi/.idea/inspectionProfiles/Project_Default.xml +++ b/izzivi/.idea/inspectionProfiles/Project_Default.xml @@ -8,5 +8,6 @@ + \ No newline at end of file diff --git a/izzivi/src/izziv4/Izziv4.java b/izzivi/src/izziv4/Izziv4.java new file mode 100644 index 0000000..6a4bfa1 --- /dev/null +++ b/izzivi/src/izziv4/Izziv4.java @@ -0,0 +1,400 @@ +package izziv4; + +class CollectionException extends Exception { + public CollectionException(String msg) { + super(msg); + } +} + +interface Collection { + static final String ERR_MSG_EMPTY = "Collection is empty."; + + boolean isEmpty(); + + int size(); + + String toString(); +} + +interface Queue extends Collection { + T front() throws CollectionException; + + void enqueue(T x); + + T dequeue() throws CollectionException; +} + +interface PriorityQueue extends Queue { +} + +@SuppressWarnings("ALL") +class ArrayPQ implements PriorityQueue { + T[] array = (T[]) new Comparable[64]; + int size = 0; + int moves = 0; + int compares = 0; + + void resize() { + T[] newArray = (T[]) new Comparable[array.length * 2]; + System.arraycopy(array, 0, newArray, 0, array.length); + array = newArray; + } + + @Override + public T front() throws CollectionException { + if (isEmpty()) { + throw new CollectionException(ERR_MSG_EMPTY); + } + T max = array[0]; + for (int i = 0; i < size; i++) { + compares++; + if (array[i].compareTo(max) > 0) { + max = array[i]; + } + } + return max; + } + + @Override + public void enqueue(T x) { + if (size == array.length) { + resize(); + } + moves++; + array[size++] = x; + } + + @Override + public T dequeue() throws CollectionException { + if (isEmpty()) { + throw new CollectionException(ERR_MSG_EMPTY); + } + T max = array[0]; + int maxIndex = 0; + for (int i = 0; i < size; i++) { + compares++; + if (array[i].compareTo(max) > 0) { + max = array[i]; + maxIndex = i; + } + } + + for (int i = maxIndex; i < size - 1; i++) { + array[i] = array[i + 1]; + moves++; + } + size--; + + return max; + } + + @Override + public boolean isEmpty() { + return size == 0; + } + + @Override + public int size() { + return size; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("["); + if (size > 0) { + sb.append(array[0]); + for (int i = 1; i < size; i++) { + sb.append(", " + array[i]); + } + } + sb.append("]"); + return sb.toString(); + } +} + +@SuppressWarnings("ALL") +class ArrayHeapPQ implements PriorityQueue { + T[] array = (T[]) new Comparable[64]; + int size = 0; + int moves = 0; + int compares = 0; + + void resize() { + T[] newArray = (T[]) new Comparable[array.length * 2]; + System.arraycopy(array, 0, newArray, 0, array.length); + array = newArray; + } + + @Override + public T front() throws CollectionException { + if (isEmpty()) { + throw new CollectionException(ERR_MSG_EMPTY); + } + return array[0]; + } + + @Override + public void enqueue(T x) { + if (size == array.length) { + resize(); + } + int i = size; + array[i] = x; + size++; + + while (true) { + int p = (i - 1) / 2; + compares++; + if (array[i].compareTo(array[p]) <= 0) { + break; + } + T tmp = array[i]; + array[i] = array[p]; + array[p] = tmp; + i = p; + moves += 3; + } + } + + @Override + public T dequeue() throws CollectionException { + if (isEmpty()) { + throw new CollectionException(ERR_MSG_EMPTY); + } + T root = array[0]; + + array[0] = array[size - 1]; + array[size - 1] = root; + moves += 2; + size--; + + int i = 0; + while (true) { + int c = 2 * i + 1; + if (c >= size) break; + + int c2 = 2 * i + 2; + compares++; + if (c2 < size && array[c2].compareTo(array[c]) > 0) { + c = c2; + } + + compares++; + if (array[c].compareTo(array[i]) < 0) break; + + T tmp = array[i]; + array[i] = array[c]; + array[c] = tmp; + moves += 3; + i = c; + } + + return root; + } + + @Override + public boolean isEmpty() { + return size == 0; + } + + @Override + public int size() { + return size; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("["); + if (size > 0) { + sb.append(array[0]); + for (int i = 1; i < size; i++) { + sb.append(", " + array[i]); + } + } + sb.append("]"); + return sb.toString(); + } +} + +class Node { + T value; + Node left; + Node right; + Node parent; + + Node(T value) { + this.value = value; + } +} + +@SuppressWarnings("ALL") +class LinkedHeapPQ implements PriorityQueue { + Node root = null; + int size = 0; + int moves = 0; + int compares = 0; + + Node getNode(int index) { + if (index == 0) { + return root; + } + Node parent = getNode((index - 1) / 2); + return index % 2 == 0 ? parent.right : parent.left; + } + + @Override + public T front() throws CollectionException { + if (isEmpty()) { + throw new CollectionException(ERR_MSG_EMPTY); + } + return root.value; + } + + @Override + public void enqueue(T x) { + Node newNode = new Node(x); + if (isEmpty()) { + root = newNode; + size++; + moves++; + return; + } + + int parentIndex = (size - 1) / 2; + Node parent = getNode(parentIndex); + newNode.parent = parent; + if (size % 2 == 0) { + parent.right = newNode; + } else { + parent.left = newNode; + } + size++; + + do { + compares++; + if (newNode.value.compareTo(newNode.parent.value) < 0) { + break; + } + + T tmp = newNode.value; + newNode.value = newNode.parent.value; + newNode.parent.value = tmp; + newNode = newNode.parent; + moves += 3; + } while (newNode.parent != null); + } + + @Override + public T dequeue() throws CollectionException { + T value = root.value; + + int lastIndex = size - 1; + Node last = getNode(lastIndex); + if (last == root) { + root = null; + size = 0; + moves++; + return value; + } + + root.value = last.value; + if (lastIndex % 2 == 0) { + last.parent.right = null; + } else { + last.parent.left = null; + } + size--; + + Node node = root; + while (true) { + if (node.left == null) break; + Node child = node.left; + compares++; + if (node.right != null) { + compares++; + if (node.left.value.compareTo(node.right.value) < 0) { + child = node.right; + } + } + + compares++; + if (node.value.compareTo(child.value) > 0) break; + + T tmp = child.value; + child.value = node.value; + node.value = tmp; + node = child; + moves += 3; + } + + return value; + } + + @Override + public boolean isEmpty() { + return size == 0; + } + + @Override + public int size() { + return size; + } +} + +@SuppressWarnings("ALL") +public class Izziv4 { + public static void main(String[] args) throws CollectionException { + System.out.println("Objekti: Integer"); + System.out.println("Operacije: 10000 enqueue + 10000 (dequeue+enqueue+front)"); + System.out.println(); + System.out.println("Implementacija Čas [ms] Premikov Primerjav"); + System.out.println("------------------------------------------------------------"); + + long start = System.nanoTime(); + ArrayPQ arrayPQ = new ArrayPQ<>(); + for (int i = 0; i < 10000; i++) { + arrayPQ.enqueue((int) (Math.random() * 10000)); + } + for (int i = 0; i < 10000; i++) { + arrayPQ.dequeue(); + arrayPQ.enqueue((int) (Math.random() * 10000)); + arrayPQ.front(); + } + long end = System.nanoTime(); + + System.out.println("Neurejeno polje " + (end - start) / 1000000 + " " + arrayPQ.moves + " " + arrayPQ.compares); + + + start = System.nanoTime(); + ArrayHeapPQ arrayHeapPQ = new ArrayHeapPQ<>(); + for (int i = 0; i < 10000; i++) { + arrayHeapPQ.enqueue((int) (Math.random() * 10000)); + } + for (int i = 0; i < 10000; i++) { + arrayHeapPQ.dequeue(); + arrayHeapPQ.enqueue((int) (Math.random() * 10000)); + arrayHeapPQ.front(); + } + end = System.nanoTime(); + + System.out.println("Implicitna kopica " + (end - start) / 1000000 + " " + arrayHeapPQ.moves + " " + arrayHeapPQ.compares); + + + start = System.nanoTime(); + LinkedHeapPQ linkedHeapPQ = new LinkedHeapPQ<>(); + for (int i = 0; i < 10000; i++) { + linkedHeapPQ.enqueue((int) (Math.random() * 10000)); + } + for (int i = 0; i < 10000; i++) { + linkedHeapPQ.dequeue(); + linkedHeapPQ.enqueue((int) (Math.random() * 10000)); + linkedHeapPQ.front(); + } + end = System.nanoTime(); + + System.out.println("Eksplicitna kopica " + (end - start) / 1000000 + " " + linkedHeapPQ.moves + " " + linkedHeapPQ.compares); + } +} + diff --git a/izzivi/src/izziv4/rezultati.png b/izzivi/src/izziv4/rezultati.png new file mode 100644 index 0000000000000000000000000000000000000000..5df40ecb6a69c80eb5d710c48c8a2a4641300dcf GIT binary patch literal 19805 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

-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 Q;7hfcwZn