diff --git a/src/sorts/OptimizedFlippedMinHeapSort.java b/src/sorts/OptimizedFlippedMinHeapSort.java new file mode 100644 index 00000000..d39a65da --- /dev/null +++ b/src/sorts/OptimizedFlippedMinHeapSort.java @@ -0,0 +1,70 @@ +package sorts; + +import templates.Sort; +import utils.Delays; +import utils.Highlights; +import utils.Reads; +import utils.Writes; + +/* + * +Copyright (c) rosettacode.org. +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 +or any later version published by the Free Software Foundation; +with no Invariant Sections, no Front-Cover Texts, and no Back-Cover +Texts. A copy of the license is included in the section entitled "GNU +Free Documentation License". + * + */ + +/* +modified by Lucy Phipps from ../templates/OptimizedHeapSorting.java and OptimizedMinHeapSort.java +the only real changes are subtracting every array access from (length - 1) +and removing the Writes.reverse() at the end +the rest is just compacting the code a bit +*/ + +final public class OptimizedFlippedMinHeapSort extends Sort { + public OptimizedFlippedMinHeapSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) { + super(delayOps, markOps, readOps, writeOps); + this.setSortPromptID("Optimized Flipped Min Heap"); + this.setRunAllID("Optimized Flipped Min Heap Sort"); + this.setReportSortID("Optimized Flipped Reverse Heapsort"); + this.setCategory("Selection Sorts"); + this.isComparisonBased(true); + this.isBucketSort(false); + this.isRadixSort(false); + this.isUnreasonablySlow(false); + this.setUnreasonableLimit(0); + this.isBogoSort(false); + } + private void siftDown(int[] array, int length, int root, int dist) { + int temp = array[length - root]; + while (root <= dist / 2) { + int leaf = 2 * root; + if (leaf < dist && Reads.compare(array[length - leaf], array[length - leaf - 1]) == 1) { + leaf++; + } + Highlights.markArray(1, length - root); + Highlights.markArray(2, length - leaf); + Delays.sleep(1); + if (Reads.compare(temp, array[length - leaf]) == 1) { + Writes.write(array, length - root, array[length - leaf], 0, true, false); + root = leaf; + } else break; + } + + Writes.write(array, length - root, temp, 0, true, false); + } + @Override + public void runSort(int[] array, int length, int bucketCount) { + for (int i = length / 2; i >= 1; i--) { + siftDown(array, length, i, length); + } + for (int i = length; i > 1; i--) { + Writes.swap(array, length - 1, length - i, 1, true, false); + siftDown(array, length, 1, i - 1); + } + } +} \ No newline at end of file diff --git a/src/sorts/OptimizedMaxHeapSort.java b/src/sorts/OptimizedMaxHeapSort.java new file mode 100644 index 00000000..ba8e56d2 --- /dev/null +++ b/src/sorts/OptimizedMaxHeapSort.java @@ -0,0 +1,45 @@ +package sorts; + +import templates.OptimizedHeapSorting; +import utils.Delays; +import utils.Highlights; +import utils.Reads; +import utils.Writes; + +/* + * +Copyright (c) rosettacode.org. +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 +or any later version published by the Free Software Foundation; +with no Invariant Sections, no Front-Cover Texts, and no Back-Cover +Texts. A copy of the license is included in the section entitled "GNU +Free Documentation License". + * + */ + +final public class OptimizedMaxHeapSort extends OptimizedHeapSorting { + public OptimizedMaxHeapSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) { + super(delayOps, markOps, readOps, writeOps); + + this.setSortPromptID("Optimized Max Heap"); + this.setRunAllID("Optimized Max Heap Sort"); + this.setReportSortID("Optimized Heapsort"); + this.setCategory("Selection Sorts"); + this.isComparisonBased(true); + this.isBucketSort(false); + this.isRadixSort(false); + this.isUnreasonablySlow(false); + this.setUnreasonableLimit(0); + this.isBogoSort(false); + } + + public void customHeapSort(int[] array, int start, int length, double sleep) { + this.heapSort(array, start, length, sleep, true); + } + + @Override + public void runSort(int[] array, int length, int bucketCount) { + this.heapSort(array, 0, length, 1, true); + } +} \ No newline at end of file diff --git a/src/sorts/OptimizedMinHeapSort.java b/src/sorts/OptimizedMinHeapSort.java new file mode 100644 index 00000000..b50a2cbf --- /dev/null +++ b/src/sorts/OptimizedMinHeapSort.java @@ -0,0 +1,41 @@ +package sorts; + +import templates.OptimizedHeapSorting; +import utils.Delays; +import utils.Highlights; +import utils.Reads; +import utils.Writes; + +/* + * +Copyright (c) rosettacode.org. +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 +or any later version published by the Free Software Foundation; +with no Invariant Sections, no Front-Cover Texts, and no Back-Cover +Texts. A copy of the license is included in the section entitled "GNU +Free Documentation License". + * + */ + +final public class OptimizedMinHeapSort extends OptimizedHeapSorting { + public OptimizedMinHeapSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) { + super(delayOps, markOps, readOps, writeOps); + + this.setSortPromptID("Optimized Min Heap"); + this.setRunAllID("Optimized Min Heap Sort"); + this.setReportSortID("Optimized Reverse Heapsort"); + this.setCategory("Selection Sorts"); + this.isComparisonBased(true); + this.isBucketSort(false); + this.isRadixSort(false); + this.isUnreasonablySlow(false); + this.setUnreasonableLimit(0); + this.isBogoSort(false); + } + + @Override + public void runSort(int[] array, int length, int bucketCount) { + this.heapSort(array, 0, length, 1, false); + } +} \ No newline at end of file diff --git a/src/sorts/OptimizedTernaryHeapSort.java b/src/sorts/OptimizedTernaryHeapSort.java new file mode 100644 index 00000000..87b465bc --- /dev/null +++ b/src/sorts/OptimizedTernaryHeapSort.java @@ -0,0 +1,84 @@ +package sorts; + +import templates.Sort; +import utils.Delays; +import utils.Highlights; +import utils.Reads; +import utils.Writes; + +final public class OptimizedTernaryHeapSort extends Sort { + public OptimizedTernaryHeapSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) { + super(delayOps, markOps, readOps, writeOps); + + this.setSortPromptID("Optimized Ternary Heap"); + this.setRunAllID("Optimized Ternary Heap Sort"); + this.setReportSortID("Optimized Ternary Heapsort"); + this.setCategory("Selection Sorts"); + this.isComparisonBased(true); + this.isBucketSort(false); + this.isRadixSort(false); + this.isUnreasonablySlow(false); + this.setUnreasonableLimit(0); + this.isBogoSort(false); + } + + // TERNARY HEAP SORT - written by qbit + // https://codereview.stackexchange.com/questions/63384/binary-heapsort-and-ternary-heapsort-implementation + + private int heapSize; + + private static int leftBranch(int i) { + return 3 * i + 1; + } + + private static int middleBranch(int i) { + return 3 * i + 2; + } + + private static int rightBranch(int i) { + return 3 * i + 3; + } + + private void maxHeapify(int[] array, int i) { + int temp = array[i], root = i; + while(this.leftBranch(root) <= this.heapSize) { + int leftChild = OptimizedTernaryHeapSort.leftBranch(root); + int rightChild = OptimizedTernaryHeapSort.rightBranch(root); + int middleChild = OptimizedTernaryHeapSort.middleBranch(root); + int largest = leftChild; + + if(rightChild <= heapSize && Reads.compare(array[rightChild], array[largest]) > 0) { + largest = rightChild; + } + + if(middleChild <= heapSize && Reads.compare(array[middleChild], array[largest]) > 0) { + largest = middleChild; + } + + if(Reads.compare(array[largest], temp) > 0) { + Writes.write(array, root, array[largest], 1, true, false); + root = largest; + } else break; + } + + Writes.write(array, root, temp, 1, true, false); + } + + private void buildMaxTernaryHeap(int[] array, int length) { + this.heapSize = length - 1; + for(int i = this.heapSize / 3; i >= 0; i--) + this.maxHeapify(array, i); + } + + @Override + public void runSort(int[] array, int length, int bucketCount) { + this.buildMaxTernaryHeap(array, length); + + for(int i = length - 1; i > 0; i--){ + Writes.swap(array, 0, i, 1, true, false); //add last element on array, i.e heap root + + this.heapSize--; //shrink heap by 1 + this.maxHeapify(array, 0); + } + } +} \ No newline at end of file diff --git a/src/templates/OptimizedHeapSorting.java b/src/templates/OptimizedHeapSorting.java new file mode 100644 index 00000000..2162a3b6 --- /dev/null +++ b/src/templates/OptimizedHeapSorting.java @@ -0,0 +1,68 @@ +package templates; + +import utils.Delays; +import utils.Highlights; +import utils.Reads; +import utils.Writes; + +/* + * +Copyright (c) rosettacode.org. +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 +or any later version published by the Free Software Foundation; +with no Invariant Sections, no Front-Cover Texts, and no Back-Cover +Texts. A copy of the license is included in the section entitled "GNU +Free Documentation License". + * + */ + +public abstract class OptimizedHeapSorting extends Sort { + protected OptimizedHeapSorting(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) { + super(delayOps, markOps, readOps, writeOps); + } + + private void siftDown(int[] array, int root, int dist, int start, double sleep, boolean isMax) { + int compareVal = isMax ? -1 : 1; + + int temp = array[start + root - 1]; + while (root <= dist / 2) { + int leaf = 2 * root; + if (leaf < dist && Reads.compare(array[start + leaf - 1], array[start + leaf]) == compareVal) { + leaf++; + } + Highlights.markArray(1, start + root - 1); + Highlights.markArray(2, start + leaf - 1); + Delays.sleep(sleep); + if (Reads.compare(temp, array[start + leaf - 1]) == compareVal) { + Writes.write(array, start + root - 1, array[start + leaf - 1], 0, true, false); + root = leaf; + } + else break; + } + + Writes.write(array, start + root - 1, temp, 0, true, false); + } + + private void heapify(int[] arr, int low, int high, double sleep, boolean isMax) { + int length = high - low; + for (int i = length / 2; i >= 1; i--) { + siftDown(arr, i, length, low, sleep, isMax); + } + } + + // This version of heap sort works for max and min variants, alongside sorting + // partial ranges of an array. + protected void heapSort(int[] arr, int start, int length, double sleep, boolean isMax) { + heapify(arr, start, length, sleep, isMax); + + for (int i = length - start; i > 1; i--) { + Writes.swap(arr, start, start + i - 1, sleep, true, false); + siftDown(arr, 1, i - 1, start, sleep, isMax); + } + + if(!isMax) { + Writes.reversal(arr, start, start + length - 1, 1, true, false); + } + } +} \ No newline at end of file