From 9e5cb32e09a902b237f3789a260240e5e9a7d603 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Tue, 28 May 2024 14:29:18 +0530 Subject: [PATCH 01/32] Adding Skeleton --- src/main/java/com/thealgorithms/sorts/SmoothSort.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/com/thealgorithms/sorts/SmoothSort.java diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java new file mode 100644 index 000000000000..bb2343e87c54 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -0,0 +1,11 @@ +package com.thealgorithms.sorts; + +public class SmoothSort implements SortAlgorithm { + + @Override + public > T[] sort(T[] unsorted) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'sort'"); + } + +} From 9ff4e85a045534fbb466d60fc3fd756d71e54151 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Wed, 29 May 2024 17:59:25 +0530 Subject: [PATCH 02/32] Understanding Heap Sort --- .../com/thealgorithms/sorts/SmoothSort.java | 63 ++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index bb2343e87c54..c618476bec51 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -1,11 +1,70 @@ package com.thealgorithms.sorts; +import java.util.ArrayList; +import java.util.List; + public class SmoothSort implements SortAlgorithm { @Override public > T[] sort(T[] unsorted) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'sort'"); + //TODO: Pending implementation + + return unsorted; + } + + private static List generateLeonardoNumbers(int maxIndex) { + List leonardoNumbers = new ArrayList<>(); + // First two numbers of the Leonardo Series are 1 + leonardoNumbers.add(1); + leonardoNumbers.add(1); + + for (int i = 2; i <= maxIndex; i++) { + int nextNumber = leonardoNumbers.get(i - 1) + leonardoNumbers.get(i - 2) + 1; + leonardoNumbers.add(nextNumber); + } + + return leonardoNumbers; + } + + private static > void heapify(T[] array, int end, int[] heaps, int size, List leonardoNumbers) { + //TODO: Pending implementation + } + + private static void swap(T[] array, int i, int j) { + T temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + + + // SINCE THIS IS ENHANCEMENT OF HEAP SORT THIS COMMIT WILL HELP ME UNDERSTAND HEAPSORT AND THEN IMPROVE IT + + public void buildHeap() { + // For ith element + // Left node is present at (2*i)+1 + // Right node is present at (2*i)+2 + // Parent node is at (i-1)/2 + } + + public void buildMaxHeap() { + // In Max heap parent node is always greater than or equal to child node + // For everey element at index i + // Compatre if element at i is greater than element at (i-2)/2 [PARENT NODE] + // if true + // then swap + // if false + // then increment i + } + + public void heapsort() { + // build heap from the input + // start_index = 0 + // end_index = arr.length + + // do till exd_index = start_index + // build max heap + // swap elements start_index and end_index (as largest element is present at start_index and needs to be moved to end_index) + // end_index = end_index - 1 } } From 69b24a86adc3d079066dc520c176b362ed4792e7 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Thu, 30 May 2024 18:36:24 +0530 Subject: [PATCH 03/32] Implement merge sort next step is to improve it to leonardo sort --- .../com/thealgorithms/sorts/SmoothSort.java | 83 +++++++++++++++++-- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index c618476bec51..b031b96e4695 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -39,24 +39,42 @@ private static void swap(T[] array, int i, int j) { // SINCE THIS IS ENHANCEMENT OF HEAP SORT THIS COMMIT WILL HELP ME UNDERSTAND HEAPSORT AND THEN IMPROVE IT - public void buildHeap() { + + public static void buildHeap() { // For ith element // Left node is present at (2*i)+1 // Right node is present at (2*i)+2 // Parent node is at (i-1)/2 } - public void buildMaxHeap() { + public static Integer[] buildMaxHeap(Integer[] array, int endIndex) { // In Max heap parent node is always greater than or equal to child node // For everey element at index i - // Compatre if element at i is greater than element at (i-2)/2 [PARENT NODE] + // Compatre if element at i is greater than element at (i-2)/2 // if true - // then swap + // then swap and keep on swapping till false or till you reach root node(index 0) // if false // then increment i + for(int i = 0; i <= endIndex; i++) { + int parent_index = (i-2)/2; + if (parent_index < 0) continue; // no parent for root node, I guess I can change the iteration from 1 + int current_index = i; + while(array[current_index] > array[parent_index]) { + int temp = array[current_index]; + array[current_index] = array[parent_index]; + array[parent_index] = temp; + + current_index = parent_index; + parent_index = (current_index-2)/2; + + if(current_index == 0) break; + } + } + + return array; } - public void heapsort() { + public static Integer[] heapsort(Integer[] array) { // build heap from the input // start_index = 0 // end_index = arr.length @@ -65,6 +83,59 @@ public void heapsort() { // build max heap // swap elements start_index and end_index (as largest element is present at start_index and needs to be moved to end_index) // end_index = end_index - 1 + + buildHeap(); + int startIndex = 0; + int endIndex = array.length - 1; + + while(endIndex != startIndex) { + array = buildMaxHeap(array , endIndex); + + int temp = array[startIndex]; + array[startIndex] = array[endIndex]; + array[endIndex] = temp; + + endIndex = endIndex -1; + } + + + return array; + } + + public static void main(String args[]) { + // This is an existing test case, remove this after implementation is verified + Integer[] array = new Integer[] {60, 7, 55, 9, 999, 3}; + Integer[] expected = new Integer[] {3, 7, 9, 55, 60, 999}; + + Integer[] sorted = heapsort(array); + System.out.println(myAssertArrayEquals(expected, sorted)); + } + + //Because Why not? Need to remove this + public static boolean myAssertArrayEquals(Integer[] expected, Integer[] actual) { + // Check if both arrays are null + if (expected == null && actual == null) { + return true; + } + + // Check if one of the arrays is null + if (expected == null || actual == null) { + return false; + } + + // Check if the lengths of the arrays are different + if (expected.length != actual.length) { + return false; + } + + // Compare each element of the arrays + for (int i = 0; i < expected.length; i++) { + if (!expected[i].equals(actual[i])) { + return false; + } + } + + // If all elements are equal + return true; } - } From 6de405923c25d0405930868fdb46e2e6a20384d6 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Fri, 14 Jun 2024 19:21:05 +0530 Subject: [PATCH 04/32] Smooth Sort impl, needs cleaning. --- .../com/thealgorithms/sorts/SmoothSort.java | 291 +++++++++++++++--- 1 file changed, 241 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index b031b96e4695..e3c259ffc98c 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -1,45 +1,10 @@ package com.thealgorithms.sorts; - +// Java implementation import java.util.ArrayList; -import java.util.List; - -public class SmoothSort implements SortAlgorithm { - - @Override - public > T[] sort(T[] unsorted) { - //TODO: Pending implementation - - return unsorted; - } - - private static List generateLeonardoNumbers(int maxIndex) { - List leonardoNumbers = new ArrayList<>(); - // First two numbers of the Leonardo Series are 1 - leonardoNumbers.add(1); - leonardoNumbers.add(1); - - for (int i = 2; i <= maxIndex; i++) { - int nextNumber = leonardoNumbers.get(i - 1) + leonardoNumbers.get(i - 2) + 1; - leonardoNumbers.add(nextNumber); - } - - return leonardoNumbers; - } - - private static > void heapify(T[] array, int end, int[] heaps, int size, List leonardoNumbers) { - //TODO: Pending implementation - } - - private static void swap(T[] array, int i, int j) { - T temp = array[i]; - array[i] = array[j]; - array[j] = temp; - } +import java.util.Arrays; +public class SmoothSort { - // SINCE THIS IS ENHANCEMENT OF HEAP SORT THIS COMMIT WILL HELP ME UNDERSTAND HEAPSORT AND THEN IMPROVE IT - - public static void buildHeap() { // For ith element // Left node is present at (2*i)+1 @@ -47,6 +12,16 @@ public static void buildHeap() { // Parent node is at (i-1)/2 } + public static int[] getLeonardoNumbers() { + int[] lenardoNumbers = { + 1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891, + 35421, 57313, 92735, 150049, 242785, 392835, 635621, 1028457, 1664079, 2692537, 4356617, 7049155, + 1405773, 18454929, 29860703, 48315633, 78176337, 126491971, 204668309, 331160281, 535828591 + }; + + return lenardoNumbers; + } + public static Integer[] buildMaxHeap(Integer[] array, int endIndex) { // In Max heap parent node is always greater than or equal to child node // For everey element at index i @@ -83,32 +58,248 @@ public static Integer[] heapsort(Integer[] array) { // build max heap // swap elements start_index and end_index (as largest element is present at start_index and needs to be moved to end_index) // end_index = end_index - 1 - - buildHeap(); + int length = array.length; int startIndex = 0; - int endIndex = array.length - 1; + int endIndex = length - 1; + + int lenardoHeapSize = 0; // start with size 0 + int leonardoLevels = 0; + + while(lenardoHeapSize < length) { + // if two trees with consequtive level + // combine them to get new tree + // else if there is no Level 1, add the node as level 1 + // else add the node as Level 0 + + // restore heap property + + + // System.out.println("HEAPSIZE = " + lenardoHeapSize); + // System.out.println("leonardoLevels = " + leonardoLevels); + // System.out.println("==============================================="); + + int[] consecutiveTreeIndices = findConsecutiveLeonardoTrees(leonardoLevels); + if(consecutiveTreeIndices[0] != -1 && consecutiveTreeIndices[1] != -1) { + // combine the trees + // update leonardoLevels + leonardoLevels = leonardoLevels & ~(1 << consecutiveTreeIndices[0]); + leonardoLevels = leonardoLevels & ~(1 << consecutiveTreeIndices[1]); + leonardoLevels = leonardoLevels | (1 << consecutiveTreeIndices[1] + 1); + } + else if (((leonardoLevels & 2) == 0)) { + // add the element at level 1 tree + // update lenardoLevels + + leonardoLevels = leonardoLevels | (1 << 1); + } + else {// (leonardoLevels & 1) == 0 + // add the element at level 0 tree if level 1 is present + // update lenardoLevels - while(endIndex != startIndex) { - array = buildMaxHeap(array , endIndex); + leonardoLevels = leonardoLevels | (1 << 0); + } + + // perform correction + lenardoHeapSize++; + array = shiftRoot(leonardoLevels, lenardoHeapSize, array); + // maxHeapify(); + } + + // while(endIndex != startIndex) { + // array = buildMaxHeap(array , endIndex); + + // int temp = array[startIndex]; + // array[startIndex] = array[endIndex]; + // array[endIndex] = temp; + + // endIndex = endIndex -1; + // } + + // Now our Leonardo heap is fully ready, start extracting the max + while (lenardoHeapSize > 0) { + int[] currentLeonardoTrees = findAllLeonardoTrees(leonardoLevels); // maybe try find last tree level + int lastTreeLevel = currentLeonardoTrees[0]; + + // destroy the current level + leonardoLevels = leonardoLevels & ~(1 << lastTreeLevel); + if(lastTreeLevel != 0 && lastTreeLevel != 1) { + // if level is not L1 or L0 + // create two smaller sublevels + leonardoLevels = leonardoLevels | (1 << lastTreeLevel - 1); + leonardoLevels = leonardoLevels | (1 << lastTreeLevel - 2); + } - int temp = array[startIndex]; - array[startIndex] = array[endIndex]; - array[endIndex] = temp; + lenardoHeapSize--; + array = shiftRoot(leonardoLevels, lenardoHeapSize, array); - endIndex = endIndex -1; - } + } return array; } + public static int[] findConsecutiveLeonardoTrees(int num) { + int prevOneIndex = -1; // Initialize to -1 to handle leading 1s + int currentBit; + + int[] answer = new int[] {-1, -1}; + for (int i = 0; num > 0; i++) { + currentBit = num & 1; + if (currentBit == 1) { + if (prevOneIndex != -1) { + answer[0] = prevOneIndex; + answer[1] = i; + + // Found consecutive ones + } + prevOneIndex = i; + } else { + prevOneIndex = -1; // Reset if encounter 0 + } + num >>>= 1; // Right shift to process next bit + } + return answer; // No consecutive ones found + } + + public static int[] findAllLeonardoTrees(int num) { + int setBitCount = 0; + for (int i = 0; i < Integer.SIZE; i++) { + if ((num & (1 << i)) != 0) { + setBitCount++; + } + } + + int[] setBitIndexes = new int[setBitCount]; // Create array with appropriate size + int index = 0; + for (int i = 0; i < Integer.SIZE; i++) { + if ((num & (1 << i)) != 0) { + setBitIndexes[index++] = i; + } + } + return setBitIndexes; + } + + public static Integer[] shiftRoot(int lenardoLevels, int lenardoHeapSize, Integer[] array) { + if (lenardoHeapSize == 0) { + return array; + } + int[] currentLeonardoTrees = findAllLeonardoTrees(lenardoLevels); + int[] leonardoNumbers = getLeonardoNumbers(); + // System.out.println("Current number of leonardo trees in leonardo heap = " + currentLeonardoTrees.length); + // System.out.println("Current lenardoHeapSize " + lenardoHeapSize); + // System.out.println("Size of the leonardo trees are : "); + int prevTreeSizeCumulative = 0; + ArrayList treeSizeList = new ArrayList(); + ArrayList rootNodeIndex = new ArrayList(); + for(int i = currentLeonardoTrees.length - 1; i >=0 ; i--) { + int currentTreeSize = leonardoNumbers[currentLeonardoTrees[i]]; + // System.out.println("Size of current tree = " + currentTreeSize + " "); + // System.out.println("Root node of current tree = " + array[prevTreeSizeCumulative + currentTreeSize - 1]); + // System.out.println("Root node index of current tree = " + (prevTreeSizeCumulative + currentTreeSize - 1)); + treeSizeList.add(currentTreeSize); + rootNodeIndex.add(prevTreeSizeCumulative + currentTreeSize - 1); + prevTreeSizeCumulative = prevTreeSizeCumulative + currentTreeSize; + } + + int rootNodeIndexSize = rootNodeIndex.size(); // should be same as currentLeonardoTrees.length + int rootNodeIndexForHeapify = rootNodeIndex.getLast(); //default value for heapify + int treeSizeForHeapify = treeSizeList.getLast(); + for(int i = 1; i < rootNodeIndexSize; i++) { // iterate form 1 because there is no left of the left-most tree + int j = i; + while (j > 0 && array[rootNodeIndex.get(j-1)] > array[rootNodeIndex.get(j)]) { + int currentTreeSize = treeSizeList.get(j); + if(currentTreeSize >= 3) { //has children + //if greater than two children then swap + if(array[rootNodeIndex.get(j-1)] > array[rootNodeIndex.get(j) - 1] && array[rootNodeIndex.get(j-1)] > array[rootNodeIndex.get(j) - 2]) { + //swap + int temp = array[rootNodeIndex.get(j-1)]; + array[rootNodeIndex.get(j-1)] = array[rootNodeIndex.get(j)]; + array[rootNodeIndex.get(j)] = temp; + rootNodeIndexForHeapify = rootNodeIndex.get(j-1); + treeSizeForHeapify = treeSizeList.get(j-1); + } + } + else{ + // swap + int temp = array[rootNodeIndex.get(j-1)]; + array[rootNodeIndex.get(j-1)] = array[rootNodeIndex.get(j)]; + array[rootNodeIndex.get(j)] = temp; + rootNodeIndexForHeapify = rootNodeIndex.get(j-1); + treeSizeForHeapify = treeSizeList.get(j-1); + } + + j--; + } + + } + + array = maxHeapify(rootNodeIndexForHeapify, treeSizeForHeapify, array); + return array; + } + + public static Integer[] maxHeapify(int rootNodeIndex, int treeSizeForHeapify, Integer[] array) { + int startNodeIndex = rootNodeIndex; + int endNodeIndex = rootNodeIndex - treeSizeForHeapify + 1; + + // This is a heap where the root node is the end index of the array + // The left child node for an element i is 2i - n + // The right child node for an element i is 2i - n - 1 + // The parent node is n - 1 - Floor( (n-i-2)/2 ) + + if (startNodeIndex <= endNodeIndex) { + return array; + } + + for(int i = startNodeIndex ; i >= endNodeIndex ; i--) { + int parentNodeIndex = treeSizeForHeapify + endNodeIndex - 1 - ((treeSizeForHeapify - i + endNodeIndex - 2)/2); + if (parentNodeIndex > rootNodeIndex || parentNodeIndex < endNodeIndex || parentNodeIndex < i) { + continue; + } + + int currenNodeIndex = i; + while(array[currenNodeIndex] > array[parentNodeIndex]) { + int temp = array[currenNodeIndex]; + array[currenNodeIndex] = array[parentNodeIndex]; + array[parentNodeIndex] = temp; + + currenNodeIndex = parentNodeIndex; + parentNodeIndex = treeSizeForHeapify - 1 - ((treeSizeForHeapify-currenNodeIndex-2)/2); + + if(currenNodeIndex == rootNodeIndex) break; // reached the root node + } + // if the current node is greater than it's parent, keep on swaping it top + + + } + return array; + } public static void main(String args[]) { // This is an existing test case, remove this after implementation is verified - Integer[] array = new Integer[] {60, 7, 55, 9, 999, 3}; - Integer[] expected = new Integer[] {3, 7, 9, 55, 60, 999}; + Integer[] array = new Integer[] {50,23,75,18,34,11,67,29,3,45,88,62,1,91,40}; + Integer[] expected = new Integer[] {1,3,11,18,23,29,34,40,45,50,62,67,75,88,91}; Integer[] sorted = heapsort(array); System.out.println(myAssertArrayEquals(expected, sorted)); + + // int[] arr = {0,1,2,3,4,5,6,7,8,9,10}; + // for (int i = 0; i < 11; i++) { + // int ele = arr[i]; + // int[] answer = findConsecutiveLeonardoTrees(ele); + // System.out.println(answer[0] + " " + answer[1]); + // } + + // int[] arr = {0,1,2,3,4,5,6,7,8,9,10}; + // for (int i = 0; i < 11; i++) { + // int ele = arr[i]; + // int[] answer = findAllLeonardoTrees(ele); + // for (int j = 0; j < answer.length ; j++) { + // System.out.print(answer[j] + " "); + // } + // if (answer.length == 0) { + // System.out.print("NONE"); + // } + // System.out.println("\n==================================="); + // } } //Because Why not? Need to remove this From d6a14b62edd1faf208f52753048806fbe5eae43f Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Mon, 17 Jun 2024 17:02:34 +0530 Subject: [PATCH 05/32] Added test cases, improved code coverage. --- .../com/thealgorithms/sorts/SmoothSort.java | 235 +++++------------- .../thealgorithms/sorts/SmoothSortTest.java | 48 ++++ 2 files changed, 106 insertions(+), 177 deletions(-) create mode 100644 src/test/java/com/thealgorithms/sorts/SmoothSortTest.java diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index e3c259ffc98c..d31b114d9fd3 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -1,19 +1,18 @@ package com.thealgorithms.sorts; -// Java implementation + import java.util.ArrayList; -import java.util.Arrays; -public class SmoothSort { +/** + * Wikipedia: https://en.wikipedia.org/wiki/Smoothsort + */ +public final class SmoothSort { + + private SmoothSort() { - public static void buildHeap() { - // For ith element - // Left node is present at (2*i)+1 - // Right node is present at (2*i)+2 - // Parent node is at (i-1)/2 } - public static int[] getLeonardoNumbers() { - int[] lenardoNumbers = { + public static Integer[] getLeonardoNumbers() { + Integer[] lenardoNumbers = { 1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891, 35421, 57313, 92735, 150049, 242785, 392835, 635621, 1028457, 1664079, 2692537, 4356617, 7049155, 1405773, 18454929, 29860703, 48315633, 78176337, 126491971, 204668309, 331160281, 535828591 @@ -22,109 +21,47 @@ public static int[] getLeonardoNumbers() { return lenardoNumbers; } - public static Integer[] buildMaxHeap(Integer[] array, int endIndex) { - // In Max heap parent node is always greater than or equal to child node - // For everey element at index i - // Compatre if element at i is greater than element at (i-2)/2 - // if true - // then swap and keep on swapping till false or till you reach root node(index 0) - // if false - // then increment i - for(int i = 0; i <= endIndex; i++) { - int parent_index = (i-2)/2; - if (parent_index < 0) continue; // no parent for root node, I guess I can change the iteration from 1 - int current_index = i; - while(array[current_index] > array[parent_index]) { - int temp = array[current_index]; - array[current_index] = array[parent_index]; - array[parent_index] = temp; - - current_index = parent_index; - parent_index = (current_index-2)/2; - - if(current_index == 0) break; - } - } - - return array; - } - - public static Integer[] heapsort(Integer[] array) { - // build heap from the input - // start_index = 0 - // end_index = arr.length - - // do till exd_index = start_index - // build max heap - // swap elements start_index and end_index (as largest element is present at start_index and needs to be moved to end_index) - // end_index = end_index - 1 + public static Integer[] smoothSort(Integer[] array) { int length = array.length; - int startIndex = 0; - int endIndex = length - 1; - int lenardoHeapSize = 0; // start with size 0 - int leonardoLevels = 0; + int leonardoLevels = 0; // No leonardo tree present initially while(lenardoHeapSize < length) { // if two trees with consequtive level // combine them to get new tree // else if there is no Level 1, add the node as level 1 // else add the node as Level 0 + // perform shiftRoot to restore heap property - // restore heap property - - - // System.out.println("HEAPSIZE = " + lenardoHeapSize); - // System.out.println("leonardoLevels = " + leonardoLevels); - // System.out.println("==============================================="); - - int[] consecutiveTreeIndices = findConsecutiveLeonardoTrees(leonardoLevels); - if(consecutiveTreeIndices[0] != -1 && consecutiveTreeIndices[1] != -1) { - // combine the trees - // update leonardoLevels + Integer[] consecutiveTreeIndices = findConsecutiveLeonardoTrees(leonardoLevels); + if(consecutiveTreeIndices[0] != -1) { + // if 0th or 1st index is -1 that implies there are no concequtive trees leonardoLevels = leonardoLevels & ~(1 << consecutiveTreeIndices[0]); leonardoLevels = leonardoLevels & ~(1 << consecutiveTreeIndices[1]); leonardoLevels = leonardoLevels | (1 << consecutiveTreeIndices[1] + 1); } else if (((leonardoLevels & 2) == 0)) { - // add the element at level 1 tree - // update lenardoLevels - leonardoLevels = leonardoLevels | (1 << 1); } - else {// (leonardoLevels & 1) == 0 - // add the element at level 0 tree if level 1 is present - // update lenardoLevels - + else { leonardoLevels = leonardoLevels | (1 << 0); } - // perform correction lenardoHeapSize++; array = shiftRoot(leonardoLevels, lenardoHeapSize, array); - // maxHeapify(); } - // while(endIndex != startIndex) { - // array = buildMaxHeap(array , endIndex); - - // int temp = array[startIndex]; - // array[startIndex] = array[endIndex]; - // array[endIndex] = temp; - - // endIndex = endIndex -1; - // } - // Now our Leonardo heap is fully ready, start extracting the max while (lenardoHeapSize > 0) { - int[] currentLeonardoTrees = findAllLeonardoTrees(leonardoLevels); // maybe try find last tree level - int lastTreeLevel = currentLeonardoTrees[0]; - // destroy the current level + // if level is not L1 or L0 + // create two smaller sublevels + // perform shiftRoot to restore heap property + + int lastTreeLevel = rightMostTree(leonardoLevels); // getting the right most tree + leonardoLevels = leonardoLevels & ~(1 << lastTreeLevel); if(lastTreeLevel != 0 && lastTreeLevel != 1) { - // if level is not L1 or L0 - // create two smaller sublevels leonardoLevels = leonardoLevels | (1 << lastTreeLevel - 1); leonardoLevels = leonardoLevels | (1 << lastTreeLevel - 2); } @@ -138,30 +75,41 @@ else if (((leonardoLevels & 2) == 0)) { return array; } - public static int[] findConsecutiveLeonardoTrees(int num) { - int prevOneIndex = -1; // Initialize to -1 to handle leading 1s + public static int rightMostTree(int leonardoLevels) { + // Isolate the rightmost set bit + int isolatedBit = leonardoLevels & -leonardoLevels; + int position = 0; + + while (isolatedBit > 1) { + isolatedBit >>= 1; + position++; + } + + return position; + } + + public static Integer[] findConsecutiveLeonardoTrees(int num) { + int prevOneIndex = -1; int currentBit; - int[] answer = new int[] {-1, -1}; + Integer[] answer = new Integer[] {-1, -1}; for (int i = 0; num > 0; i++) { currentBit = num & 1; if (currentBit == 1) { if (prevOneIndex != -1) { answer[0] = prevOneIndex; answer[1] = i; - - // Found consecutive ones } prevOneIndex = i; } else { - prevOneIndex = -1; // Reset if encounter 0 + prevOneIndex = -1; } - num >>>= 1; // Right shift to process next bit + num >>>= 1; } - return answer; // No consecutive ones found + return answer; } - public static int[] findAllLeonardoTrees(int num) { + public static Integer[] findAllLeonardoTrees(int num) { int setBitCount = 0; for (int i = 0; i < Integer.SIZE; i++) { if ((num & (1 << i)) != 0) { @@ -169,7 +117,7 @@ public static int[] findAllLeonardoTrees(int num) { } } - int[] setBitIndexes = new int[setBitCount]; // Create array with appropriate size + Integer[] setBitIndexes = new Integer[setBitCount]; int index = 0; for (int i = 0; i < Integer.SIZE; i++) { if ((num & (1 << i)) != 0) { @@ -183,33 +131,26 @@ public static Integer[] shiftRoot(int lenardoLevels, int lenardoHeapSize, Intege if (lenardoHeapSize == 0) { return array; } - int[] currentLeonardoTrees = findAllLeonardoTrees(lenardoLevels); - int[] leonardoNumbers = getLeonardoNumbers(); - // System.out.println("Current number of leonardo trees in leonardo heap = " + currentLeonardoTrees.length); - // System.out.println("Current lenardoHeapSize " + lenardoHeapSize); - // System.out.println("Size of the leonardo trees are : "); + Integer[] currentLeonardoTrees = findAllLeonardoTrees(lenardoLevels); + Integer[] leonardoNumbers = getLeonardoNumbers(); int prevTreeSizeCumulative = 0; ArrayList treeSizeList = new ArrayList(); ArrayList rootNodeIndex = new ArrayList(); for(int i = currentLeonardoTrees.length - 1; i >=0 ; i--) { int currentTreeSize = leonardoNumbers[currentLeonardoTrees[i]]; - // System.out.println("Size of current tree = " + currentTreeSize + " "); - // System.out.println("Root node of current tree = " + array[prevTreeSizeCumulative + currentTreeSize - 1]); - // System.out.println("Root node index of current tree = " + (prevTreeSizeCumulative + currentTreeSize - 1)); treeSizeList.add(currentTreeSize); rootNodeIndex.add(prevTreeSizeCumulative + currentTreeSize - 1); prevTreeSizeCumulative = prevTreeSizeCumulative + currentTreeSize; } - - int rootNodeIndexSize = rootNodeIndex.size(); // should be same as currentLeonardoTrees.length + int rootNodeIndexForHeapify = rootNodeIndex.getLast(); //default value for heapify int treeSizeForHeapify = treeSizeList.getLast(); - for(int i = 1; i < rootNodeIndexSize; i++) { // iterate form 1 because there is no left of the left-most tree + for(int i = 1; i < currentLeonardoTrees.length; i++) { // iterate form 1 because there is no left of the left-most tree int j = i; while (j > 0 && array[rootNodeIndex.get(j-1)] > array[rootNodeIndex.get(j)]) { int currentTreeSize = treeSizeList.get(j); if(currentTreeSize >= 3) { //has children - //if greater than two children then swap + //if greater than each of two children then swap if(array[rootNodeIndex.get(j-1)] > array[rootNodeIndex.get(j) - 1] && array[rootNodeIndex.get(j-1)] > array[rootNodeIndex.get(j) - 2]) { //swap int temp = array[rootNodeIndex.get(j-1)]; @@ -252,81 +193,21 @@ public static Integer[] maxHeapify(int rootNodeIndex, int treeSizeForHeapify, In for(int i = startNodeIndex ; i >= endNodeIndex ; i--) { int parentNodeIndex = treeSizeForHeapify + endNodeIndex - 1 - ((treeSizeForHeapify - i + endNodeIndex - 2)/2); - if (parentNodeIndex > rootNodeIndex || parentNodeIndex < endNodeIndex || parentNodeIndex < i) { - continue; - } + if ((parentNodeIndex <= rootNodeIndex) && (parentNodeIndex >= i)) { + int currenNodeIndex = i; + while(array[currenNodeIndex] > array[parentNodeIndex]) { + int temp = array[currenNodeIndex]; + array[currenNodeIndex] = array[parentNodeIndex]; + array[parentNodeIndex] = temp; - int currenNodeIndex = i; - while(array[currenNodeIndex] > array[parentNodeIndex]) { - int temp = array[currenNodeIndex]; - array[currenNodeIndex] = array[parentNodeIndex]; - array[parentNodeIndex] = temp; + currenNodeIndex = parentNodeIndex; + parentNodeIndex = treeSizeForHeapify - 1 - ((treeSizeForHeapify-currenNodeIndex-2)/2); - currenNodeIndex = parentNodeIndex; - parentNodeIndex = treeSizeForHeapify - 1 - ((treeSizeForHeapify-currenNodeIndex-2)/2); - - if(currenNodeIndex == rootNodeIndex) break; // reached the root node + if(currenNodeIndex == rootNodeIndex) break; // reached the root node + } } - // if the current node is greater than it's parent, keep on swaping it top - } return array; } - public static void main(String args[]) { - // This is an existing test case, remove this after implementation is verified - Integer[] array = new Integer[] {50,23,75,18,34,11,67,29,3,45,88,62,1,91,40}; - Integer[] expected = new Integer[] {1,3,11,18,23,29,34,40,45,50,62,67,75,88,91}; - - Integer[] sorted = heapsort(array); - System.out.println(myAssertArrayEquals(expected, sorted)); - - // int[] arr = {0,1,2,3,4,5,6,7,8,9,10}; - // for (int i = 0; i < 11; i++) { - // int ele = arr[i]; - // int[] answer = findConsecutiveLeonardoTrees(ele); - // System.out.println(answer[0] + " " + answer[1]); - // } - - // int[] arr = {0,1,2,3,4,5,6,7,8,9,10}; - // for (int i = 0; i < 11; i++) { - // int ele = arr[i]; - // int[] answer = findAllLeonardoTrees(ele); - // for (int j = 0; j < answer.length ; j++) { - // System.out.print(answer[j] + " "); - // } - // if (answer.length == 0) { - // System.out.print("NONE"); - // } - // System.out.println("\n==================================="); - // } - } - - //Because Why not? Need to remove this - public static boolean myAssertArrayEquals(Integer[] expected, Integer[] actual) { - // Check if both arrays are null - if (expected == null && actual == null) { - return true; - } - - // Check if one of the arrays is null - if (expected == null || actual == null) { - return false; - } - - // Check if the lengths of the arrays are different - if (expected.length != actual.length) { - return false; - } - - // Compare each element of the arrays - for (int i = 0; i < expected.length; i++) { - if (!expected[i].equals(actual[i])) { - return false; - } - } - - // If all elements are equal - return true; - } } diff --git a/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java b/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java new file mode 100644 index 000000000000..3ef720519c1d --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java @@ -0,0 +1,48 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +public class SmoothSortTest { + + @Test + public void smoothSortSingleIntegerArray() { + Integer[] inputArray = {4}; + Integer[] outputArray = SmoothSort.smoothSort(inputArray); + Integer[] expectedOutput = {4}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void smoothSortNonDuplicateIntegerArray() { + Integer[] inputArray = {6, 1, 99, 27, 15, 23, 36}; + Integer[] outputArray = SmoothSort.smoothSort(inputArray); + Integer[] expectedOutput = {1, 6, 15, 23, 27, 36, 99}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void smoothSortDuplicateIntegerArray() { + Integer[] inputArray = {6, 1, 27, 15, 23, 27, 36, 23}; + Integer[] outputArray = SmoothSort.smoothSort(inputArray); + Integer[] expectedOutput = {1, 6, 15, 23, 23, 27, 27, 36}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void smoothSortNonDuplicateIntegerArrayWithNegativeNum() { + Integer[] inputArray = {6, -1, 99, 27, -15, 23, -36}; + Integer[] outputArray = SmoothSort.smoothSort(inputArray); + Integer[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void smoothSortDuplicateIntegerArrayWithNegativeNum() { + Integer[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23}; + Integer[] outputArray = SmoothSort.smoothSort(inputArray); + Integer[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27}; + assertArrayEquals(outputArray, expectedOutput); + } +} From 384f814f947d3ca7b0804d95e1e1ec5eeb909281 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Tue, 18 Jun 2024 14:53:28 +0530 Subject: [PATCH 06/32] Refactorization of code --- .../com/thealgorithms/sorts/SmoothSort.java | 143 ++++++++---------- 1 file changed, 66 insertions(+), 77 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index d31b114d9fd3..947754240b12 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -8,74 +8,66 @@ public final class SmoothSort { private SmoothSort() { - } public static Integer[] getLeonardoNumbers() { - Integer[] lenardoNumbers = { - 1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891, - 35421, 57313, 92735, 150049, 242785, 392835, 635621, 1028457, 1664079, 2692537, 4356617, 7049155, - 1405773, 18454929, 29860703, 48315633, 78176337, 126491971, 204668309, 331160281, 535828591 - }; - - return lenardoNumbers; - } + Integer[] leonardoNumbers = {1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891, 35421, 57313, 92735, 150049, 242785, 392835, 635621, 1028457, 1664079, 2692537, 4356617, 7049155, 1405773, 18454929, 29860703, 48315633, 78176337, 126491971, + 204668309, 331160281, 535828591}; + + return leonardoNumbers; + } public static Integer[] smoothSort(Integer[] array) { int length = array.length; - int lenardoHeapSize = 0; // start with size 0 + int leonardoHeapSize = 0; // start with size 0 int leonardoLevels = 0; // No leonardo tree present initially - while(lenardoHeapSize < length) { + while (leonardoHeapSize < length) { // if two trees with consequtive level - // combine them to get new tree + // combine them to get new tree // else if there is no Level 1, add the node as level 1 // else add the node as Level 0 // perform shiftRoot to restore heap property Integer[] consecutiveTreeIndices = findConsecutiveLeonardoTrees(leonardoLevels); - if(consecutiveTreeIndices[0] != -1) { + if (consecutiveTreeIndices[0] != -1) { // if 0th or 1st index is -1 that implies there are no concequtive trees leonardoLevels = leonardoLevels & ~(1 << consecutiveTreeIndices[0]); leonardoLevels = leonardoLevels & ~(1 << consecutiveTreeIndices[1]); leonardoLevels = leonardoLevels | (1 << consecutiveTreeIndices[1] + 1); - } - else if (((leonardoLevels & 2) == 0)) { + } else if (((leonardoLevels & 2) == 0)) { leonardoLevels = leonardoLevels | (1 << 1); - } - else { + } else { leonardoLevels = leonardoLevels | (1 << 0); } - lenardoHeapSize++; - array = shiftRoot(leonardoLevels, lenardoHeapSize, array); + leonardoHeapSize++; + array = shiftRoot(leonardoLevels, leonardoHeapSize, array); } // Now our Leonardo heap is fully ready, start extracting the max - while (lenardoHeapSize > 0) { + while (leonardoHeapSize > 0) { // destroy the current level - // if level is not L1 or L0 - // create two smaller sublevels + // if level is not L1 or L0 + // create two smaller sublevels // perform shiftRoot to restore heap property - int lastTreeLevel = rightMostTree(leonardoLevels); // getting the right most tree + int lastTreeLevel = getRightMostTree(leonardoLevels); // getting the right most tree leonardoLevels = leonardoLevels & ~(1 << lastTreeLevel); - if(lastTreeLevel != 0 && lastTreeLevel != 1) { + if (lastTreeLevel != 0 && lastTreeLevel != 1) { leonardoLevels = leonardoLevels | (1 << lastTreeLevel - 1); leonardoLevels = leonardoLevels | (1 << lastTreeLevel - 2); } - lenardoHeapSize--; - array = shiftRoot(leonardoLevels, lenardoHeapSize, array); - + leonardoHeapSize--; + array = shiftRoot(leonardoLevels, leonardoHeapSize, array); } - return array; } - public static int rightMostTree(int leonardoLevels) { + public static int getRightMostTree(int leonardoLevels) { // Isolate the rightmost set bit int isolatedBit = leonardoLevels & -leonardoLevels; int position = 0; @@ -92,43 +84,43 @@ public static Integer[] findConsecutiveLeonardoTrees(int num) { int prevOneIndex = -1; int currentBit; - Integer[] answer = new Integer[] {-1, -1}; + Integer[] answer = new Integer[] {-1, -1}; for (int i = 0; num > 0; i++) { - currentBit = num & 1; - if (currentBit == 1) { - if (prevOneIndex != -1) { - answer[0] = prevOneIndex; - answer[1] = i; + currentBit = num & 1; + if (currentBit == 1) { + if (prevOneIndex != -1) { + answer[0] = prevOneIndex; + answer[1] = i; + } + prevOneIndex = i; + } else { + prevOneIndex = -1; } - prevOneIndex = i; - } else { - prevOneIndex = -1; - } - num >>>= 1; + num >>>= 1; } return answer; - } + } public static Integer[] findAllLeonardoTrees(int num) { int setBitCount = 0; for (int i = 0; i < Integer.SIZE; i++) { - if ((num & (1 << i)) != 0) { - setBitCount++; - } + if ((num & (1 << i)) != 0) { + setBitCount++; + } } - + Integer[] setBitIndexes = new Integer[setBitCount]; int index = 0; for (int i = 0; i < Integer.SIZE; i++) { - if ((num & (1 << i)) != 0) { - setBitIndexes[index++] = i; - } + if ((num & (1 << i)) != 0) { + setBitIndexes[index++] = i; + } } return setBitIndexes; } - - public static Integer[] shiftRoot(int lenardoLevels, int lenardoHeapSize, Integer[] array) { - if (lenardoHeapSize == 0) { + + public static Integer[] shiftRoot(int lenardoLevels, int leonardoHeapSize, Integer[] array) { + if (leonardoHeapSize == 0) { return array; } Integer[] currentLeonardoTrees = findAllLeonardoTrees(lenardoLevels); @@ -136,42 +128,40 @@ public static Integer[] shiftRoot(int lenardoLevels, int lenardoHeapSize, Intege int prevTreeSizeCumulative = 0; ArrayList treeSizeList = new ArrayList(); ArrayList rootNodeIndex = new ArrayList(); - for(int i = currentLeonardoTrees.length - 1; i >=0 ; i--) { + for (int i = currentLeonardoTrees.length - 1; i >= 0; i--) { int currentTreeSize = leonardoNumbers[currentLeonardoTrees[i]]; treeSizeList.add(currentTreeSize); rootNodeIndex.add(prevTreeSizeCumulative + currentTreeSize - 1); prevTreeSizeCumulative = prevTreeSizeCumulative + currentTreeSize; } - - int rootNodeIndexForHeapify = rootNodeIndex.getLast(); //default value for heapify + + int rootNodeIndexForHeapify = rootNodeIndex.getLast(); // default value for heapify int treeSizeForHeapify = treeSizeList.getLast(); - for(int i = 1; i < currentLeonardoTrees.length; i++) { // iterate form 1 because there is no left of the left-most tree + for (int i = 1; i < currentLeonardoTrees.length; i++) { // iterate form 1 because there is no left of the left-most tree int j = i; - while (j > 0 && array[rootNodeIndex.get(j-1)] > array[rootNodeIndex.get(j)]) { + while (j > 0 && array[rootNodeIndex.get(j - 1)] > array[rootNodeIndex.get(j)]) { int currentTreeSize = treeSizeList.get(j); - if(currentTreeSize >= 3) { //has children - //if greater than each of two children then swap - if(array[rootNodeIndex.get(j-1)] > array[rootNodeIndex.get(j) - 1] && array[rootNodeIndex.get(j-1)] > array[rootNodeIndex.get(j) - 2]) { - //swap - int temp = array[rootNodeIndex.get(j-1)]; - array[rootNodeIndex.get(j-1)] = array[rootNodeIndex.get(j)]; + if (currentTreeSize >= 3) { // has children + // if greater than each of two children then swap + if (array[rootNodeIndex.get(j - 1)] > array[rootNodeIndex.get(j) - 1] && array[rootNodeIndex.get(j - 1)] > array[rootNodeIndex.get(j) - 2]) { + // swap + int temp = array[rootNodeIndex.get(j - 1)]; + array[rootNodeIndex.get(j - 1)] = array[rootNodeIndex.get(j)]; array[rootNodeIndex.get(j)] = temp; - rootNodeIndexForHeapify = rootNodeIndex.get(j-1); - treeSizeForHeapify = treeSizeList.get(j-1); + rootNodeIndexForHeapify = rootNodeIndex.get(j - 1); + treeSizeForHeapify = treeSizeList.get(j - 1); } - } - else{ + } else { // swap - int temp = array[rootNodeIndex.get(j-1)]; - array[rootNodeIndex.get(j-1)] = array[rootNodeIndex.get(j)]; + int temp = array[rootNodeIndex.get(j - 1)]; + array[rootNodeIndex.get(j - 1)] = array[rootNodeIndex.get(j)]; array[rootNodeIndex.get(j)] = temp; - rootNodeIndexForHeapify = rootNodeIndex.get(j-1); - treeSizeForHeapify = treeSizeList.get(j-1); + rootNodeIndexForHeapify = rootNodeIndex.get(j - 1); + treeSizeForHeapify = treeSizeList.get(j - 1); } j--; } - } array = maxHeapify(rootNodeIndexForHeapify, treeSizeForHeapify, array); @@ -191,22 +181,21 @@ public static Integer[] maxHeapify(int rootNodeIndex, int treeSizeForHeapify, In return array; } - for(int i = startNodeIndex ; i >= endNodeIndex ; i--) { - int parentNodeIndex = treeSizeForHeapify + endNodeIndex - 1 - ((treeSizeForHeapify - i + endNodeIndex - 2)/2); + for (int i = startNodeIndex; i >= endNodeIndex; i--) { + int parentNodeIndex = treeSizeForHeapify + endNodeIndex - 1 - ((treeSizeForHeapify - i + endNodeIndex - 2) / 2); if ((parentNodeIndex <= rootNodeIndex) && (parentNodeIndex >= i)) { int currenNodeIndex = i; - while(array[currenNodeIndex] > array[parentNodeIndex]) { + while (array[currenNodeIndex] > array[parentNodeIndex]) { int temp = array[currenNodeIndex]; array[currenNodeIndex] = array[parentNodeIndex]; array[parentNodeIndex] = temp; currenNodeIndex = parentNodeIndex; - parentNodeIndex = treeSizeForHeapify - 1 - ((treeSizeForHeapify-currenNodeIndex-2)/2); + parentNodeIndex = treeSizeForHeapify - 1 - ((treeSizeForHeapify - currenNodeIndex - 2) / 2); - if(currenNodeIndex == rootNodeIndex) break; // reached the root node + if (currenNodeIndex == rootNodeIndex) break; // reached the root node } } - } return array; } From 4f0fd7074c9536b284d6ab8207e52ea34e3c9751 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Tue, 18 Jun 2024 15:24:46 +0530 Subject: [PATCH 07/32] Fixed brackets and ran mvn checkstyle:checkstyle to ensure no more checkstyle faults --- src/main/java/com/thealgorithms/sorts/SmoothSort.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 947754240b12..2882c2305219 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -193,7 +193,9 @@ public static Integer[] maxHeapify(int rootNodeIndex, int treeSizeForHeapify, In currenNodeIndex = parentNodeIndex; parentNodeIndex = treeSizeForHeapify - 1 - ((treeSizeForHeapify - currenNodeIndex - 2) / 2); - if (currenNodeIndex == rootNodeIndex) break; // reached the root node + if (currenNodeIndex == rootNodeIndex) { + break; + } // reached the root node } } } From 0cdcba28777fadfceca8f1f21fd3e2f86de60c29 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Tue, 18 Jun 2024 15:27:00 +0530 Subject: [PATCH 08/32] Fixed a tab space issue --- src/main/java/com/thealgorithms/sorts/SmoothSort.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 2882c2305219..0f0929850a70 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -195,7 +195,7 @@ public static Integer[] maxHeapify(int rootNodeIndex, int treeSizeForHeapify, In if (currenNodeIndex == rootNodeIndex) { break; - } // reached the root node + } // reached the root node } } } From d32e435e6b244396bb7a49489c2503f730d9ca33 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Tue, 18 Jun 2024 15:43:42 +0530 Subject: [PATCH 09/32] Removed useless parenthesis. --- src/main/java/com/thealgorithms/sorts/SmoothSort.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 0f0929850a70..ded05cbce474 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -35,7 +35,7 @@ public static Integer[] smoothSort(Integer[] array) { leonardoLevels = leonardoLevels & ~(1 << consecutiveTreeIndices[0]); leonardoLevels = leonardoLevels & ~(1 << consecutiveTreeIndices[1]); leonardoLevels = leonardoLevels | (1 << consecutiveTreeIndices[1] + 1); - } else if (((leonardoLevels & 2) == 0)) { + } else if ((leonardoLevels & 2) == 0) { leonardoLevels = leonardoLevels | (1 << 1); } else { leonardoLevels = leonardoLevels | (1 << 0); From 712868e53f148b492c25f016ccc80e08c995fae3 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Mon, 24 Jun 2024 18:04:23 +0530 Subject: [PATCH 10/32] Re work, fix bugs, names etc. --- .../com/thealgorithms/sorts/SmoothSort.java | 209 ++++++++++-------- .../thealgorithms/sorts/SmoothSortTest.java | 48 ---- 2 files changed, 118 insertions(+), 139 deletions(-) delete mode 100644 src/test/java/com/thealgorithms/sorts/SmoothSortTest.java diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index ded05cbce474..93566c8847bb 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -1,75 +1,73 @@ package com.thealgorithms.sorts; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; /** * Wikipedia: https://en.wikipedia.org/wiki/Smoothsort */ -public final class SmoothSort { +public final class SmoothSort implements SortAlgorithm { - private SmoothSort() { + public SmoothSort() { } - public static Integer[] getLeonardoNumbers() { + private static Integer[] getLeonardoNumbers() { Integer[] leonardoNumbers = {1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891, 35421, 57313, 92735, 150049, 242785, 392835, 635621, 1028457, 1664079, 2692537, 4356617, 7049155, 1405773, 18454929, 29860703, 48315633, 78176337, 126491971, 204668309, 331160281, 535828591}; return leonardoNumbers; } - public static Integer[] smoothSort(Integer[] array) { + private static > void smoothSort(T[] array) { int length = array.length; int leonardoHeapSize = 0; // start with size 0 - int leonardoLevels = 0; // No leonardo tree present initially + int leonardoLevelTracker = 0; // No leonardo tree present initially while (leonardoHeapSize < length) { // if two trees with consequtive level // combine them to get new tree // else if there is no Level 1, add the node as level 1 // else add the node as Level 0 - // perform shiftRoot to restore heap property + // perform shiftRoot and restore heap property - Integer[] consecutiveTreeIndices = findConsecutiveLeonardoTrees(leonardoLevels); + Integer[] consecutiveTreeIndices = findConsecutiveLeonardoTreeIndices(leonardoLevelTracker); if (consecutiveTreeIndices[0] != -1) { // if 0th or 1st index is -1 that implies there are no concequtive trees - leonardoLevels = leonardoLevels & ~(1 << consecutiveTreeIndices[0]); - leonardoLevels = leonardoLevels & ~(1 << consecutiveTreeIndices[1]); - leonardoLevels = leonardoLevels | (1 << consecutiveTreeIndices[1] + 1); - } else if ((leonardoLevels & 2) == 0) { - leonardoLevels = leonardoLevels | (1 << 1); + leonardoLevelTracker = leonardoLevelTracker & ~(1 << consecutiveTreeIndices[0]); + leonardoLevelTracker = leonardoLevelTracker & ~(1 << consecutiveTreeIndices[1]); + leonardoLevelTracker = leonardoLevelTracker | (1 << consecutiveTreeIndices[1] + 1); + } else if ((leonardoLevelTracker & 2) == 0) { + leonardoLevelTracker = leonardoLevelTracker | (1 << 1); } else { - leonardoLevels = leonardoLevels | (1 << 0); + leonardoLevelTracker = leonardoLevelTracker | (1 << 0); } - leonardoHeapSize++; - array = shiftRoot(leonardoLevels, leonardoHeapSize, array); + shiftRootAndRestoreHeap(leonardoLevelTracker, leonardoHeapSize, array); } - // Now our Leonardo heap is fully ready, start extracting the max while (leonardoHeapSize > 0) { // destroy the current level // if level is not L1 or L0 // create two smaller sublevels - // perform shiftRoot to restore heap property + // perform shiftRoot and restore heap property - int lastTreeLevel = getRightMostTree(leonardoLevels); // getting the right most tree + int lastTreeLevel = getRightMostTree(leonardoLevelTracker); // getting the right most tree - leonardoLevels = leonardoLevels & ~(1 << lastTreeLevel); + leonardoLevelTracker = leonardoLevelTracker & ~(1 << lastTreeLevel); if (lastTreeLevel != 0 && lastTreeLevel != 1) { - leonardoLevels = leonardoLevels | (1 << lastTreeLevel - 1); - leonardoLevels = leonardoLevels | (1 << lastTreeLevel - 2); + leonardoLevelTracker = leonardoLevelTracker | (1 << lastTreeLevel - 1); + leonardoLevelTracker = leonardoLevelTracker | (1 << lastTreeLevel - 2); } leonardoHeapSize--; - array = shiftRoot(leonardoLevels, leonardoHeapSize, array); + shiftRootAndRestoreHeap(leonardoLevelTracker, leonardoHeapSize, array); } - - return array; } - public static int getRightMostTree(int leonardoLevels) { + private static int getRightMostTree(int leonardoLevelTracker) { // Isolate the rightmost set bit - int isolatedBit = leonardoLevels & -leonardoLevels; + int isolatedBit = leonardoLevelTracker & -leonardoLevelTracker; int position = 0; while (isolatedBit > 1) { @@ -80,14 +78,14 @@ public static int getRightMostTree(int leonardoLevels) { return position; } - public static Integer[] findConsecutiveLeonardoTrees(int num) { + private static Integer[] findConsecutiveLeonardoTreeIndices(int num) { int prevOneIndex = -1; - int currentBit; + int currentLevel; Integer[] answer = new Integer[] {-1, -1}; for (int i = 0; num > 0; i++) { - currentBit = num & 1; - if (currentBit == 1) { + currentLevel = num & 1; + if (currentLevel == 1) { if (prevOneIndex != -1) { answer[0] = prevOneIndex; answer[1] = i; @@ -101,7 +99,7 @@ public static Integer[] findConsecutiveLeonardoTrees(int num) { return answer; } - public static Integer[] findAllLeonardoTrees(int num) { + private static Integer[] findAllLeonardoTreeIndices(int num) { int setBitCount = 0; for (int i = 0; i < Integer.SIZE; i++) { if ((num & (1 << i)) != 0) { @@ -119,86 +117,115 @@ public static Integer[] findAllLeonardoTrees(int num) { return setBitIndexes; } - public static Integer[] shiftRoot(int lenardoLevels, int leonardoHeapSize, Integer[] array) { + private static > void shiftRootAndRestoreHeap(int lenardoLevelTracker, int leonardoHeapSize, T[] array) { + if (leonardoHeapSize == 0) { - return array; + return; } - Integer[] currentLeonardoTrees = findAllLeonardoTrees(lenardoLevels); - Integer[] leonardoNumbers = getLeonardoNumbers(); - int prevTreeSizeCumulative = 0; - ArrayList treeSizeList = new ArrayList(); - ArrayList rootNodeIndex = new ArrayList(); - for (int i = currentLeonardoTrees.length - 1; i >= 0; i--) { - int currentTreeSize = leonardoNumbers[currentLeonardoTrees[i]]; - treeSizeList.add(currentTreeSize); - rootNodeIndex.add(prevTreeSizeCumulative + currentTreeSize - 1); - prevTreeSizeCumulative = prevTreeSizeCumulative + currentTreeSize; + + Integer[] currentLeonardoTreeLevels = findAllLeonardoTreeIndices(lenardoLevelTracker); + int previousTreeSizeCumulative = 0; + ArrayList rootNodeIndices = new ArrayList(); + Collections.reverse(Arrays.asList(currentLeonardoTreeLevels)); // To get the Levels in decreasing order of levels + + // The number of roots are going to be same the the number of levels + // iterate over the currentLeonardoTreeLevels and get roots + + for (int i = 0; i < currentLeonardoTreeLevels.length; i++) { + rootNodeIndices.add(previousTreeSizeCumulative + getLeonardoNumbers()[currentLeonardoTreeLevels[i]] - 1); + previousTreeSizeCumulative = previousTreeSizeCumulative + getLeonardoNumbers()[currentLeonardoTreeLevels[i]]; } - int rootNodeIndexForHeapify = rootNodeIndex.getLast(); // default value for heapify - int treeSizeForHeapify = treeSizeList.getLast(); - for (int i = 1; i < currentLeonardoTrees.length; i++) { // iterate form 1 because there is no left of the left-most tree + int rootNodeIndexForHeapify = rootNodeIndices.getLast(); + int leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[currentLeonardoTreeLevels.length - 1]; + + for (int i = 0; i < rootNodeIndices.size(); i++) { + if (i == 0) { + continue; + } + + int currentRootNodeIndex = rootNodeIndices.get(i); + int prevRootNodeIndex = rootNodeIndices.get(i - 1); int j = i; - while (j > 0 && array[rootNodeIndex.get(j - 1)] > array[rootNodeIndex.get(j)]) { - int currentTreeSize = treeSizeList.get(j); - if (currentTreeSize >= 3) { // has children - // if greater than each of two children then swap - if (array[rootNodeIndex.get(j - 1)] > array[rootNodeIndex.get(j) - 1] && array[rootNodeIndex.get(j - 1)] > array[rootNodeIndex.get(j) - 2]) { - // swap - int temp = array[rootNodeIndex.get(j - 1)]; - array[rootNodeIndex.get(j - 1)] = array[rootNodeIndex.get(j)]; - array[rootNodeIndex.get(j)] = temp; - rootNodeIndexForHeapify = rootNodeIndex.get(j - 1); - treeSizeForHeapify = treeSizeList.get(j - 1); + while (array[prevRootNodeIndex].compareTo(array[currentRootNodeIndex]) > 0) { + int currentLeonardoLevel = currentLeonardoTreeLevels[j]; + if (currentLeonardoLevel > 1) { + // compare child and swap + + int indexOfRightChild = rootNodeIndices.get(j) - 1; // right child is of level n-2 + int indexOfLeftChild = rootNodeIndices.get(j) - 1 - getLeonardoNumbers()[currentLeonardoLevel - 2]; + if (array[prevRootNodeIndex].compareTo(array[indexOfRightChild]) > 0 && array[prevRootNodeIndex].compareTo(array[indexOfLeftChild]) > 0) { + swap(array, prevRootNodeIndex, currentRootNodeIndex); + rootNodeIndexForHeapify = prevRootNodeIndex; + leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; + } else { + maxHeapifyLeonardoTree(currentRootNodeIndex, currentLeonardoLevel, array); } } else { // swap - int temp = array[rootNodeIndex.get(j - 1)]; - array[rootNodeIndex.get(j - 1)] = array[rootNodeIndex.get(j)]; - array[rootNodeIndex.get(j)] = temp; - rootNodeIndexForHeapify = rootNodeIndex.get(j - 1); - treeSizeForHeapify = treeSizeList.get(j - 1); + swap(array, prevRootNodeIndex, currentRootNodeIndex); + rootNodeIndexForHeapify = prevRootNodeIndex; + leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; + } + j = j - 1; + if (j == i - 1) { + maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); + break; } - j--; + currentRootNodeIndex = rootNodeIndices.get(j); + prevRootNodeIndex = rootNodeIndices.get(j - 1); } } - array = maxHeapify(rootNodeIndexForHeapify, treeSizeForHeapify, array); - return array; + maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); // for the last tree if needed } - public static Integer[] maxHeapify(int rootNodeIndex, int treeSizeForHeapify, Integer[] array) { - int startNodeIndex = rootNodeIndex; - int endNodeIndex = rootNodeIndex - treeSizeForHeapify + 1; + private static void swap(T[] array, int idx, int idy) { + T swap = array[idx]; + array[idx] = array[idy]; + array[idy] = swap; + } - // This is a heap where the root node is the end index of the array - // The left child node for an element i is 2i - n - // The right child node for an element i is 2i - n - 1 - // The parent node is n - 1 - Floor( (n-i-2)/2 ) + private static > void maxHeapifyLeonardoTree(int rootNodeIndex, int currentLeonardoLevel, T[] array) { + // A leonardo tree of level n is just 1 node(the root) plus the leonardo tree of n-1 level(left child) plus leonardo tree of n-2 level(right child) + // To maxheapify a leonardo tree we need to compare the current root and roots of it's left and right subtree + // We recursively hepify the left and right subtrees using the currentLeonardoLevel - if (startNodeIndex <= endNodeIndex) { - return array; + // BASE CASE + if (currentLeonardoLevel == 0 || currentLeonardoLevel == 1) { + return; // Trees with one node are in already max-heapified. } - for (int i = startNodeIndex; i >= endNodeIndex; i--) { - int parentNodeIndex = treeSizeForHeapify + endNodeIndex - 1 - ((treeSizeForHeapify - i + endNodeIndex - 2) / 2); - if ((parentNodeIndex <= rootNodeIndex) && (parentNodeIndex >= i)) { - int currenNodeIndex = i; - while (array[currenNodeIndex] > array[parentNodeIndex]) { - int temp = array[currenNodeIndex]; - array[currenNodeIndex] = array[parentNodeIndex]; - array[parentNodeIndex] = temp; - - currenNodeIndex = parentNodeIndex; - parentNodeIndex = treeSizeForHeapify - 1 - ((treeSizeForHeapify - currenNodeIndex - 2) / 2); - - if (currenNodeIndex == rootNodeIndex) { - break; - } // reached the root node - } + int currentRootNodeIndex = rootNodeIndex; + int rightChildIndex = rootNodeIndex - 1; + int leftChildIndex = rootNodeIndex - getLeonardoNumbers()[currentLeonardoLevel - 2] - 1; + int childIndexForSwap = -1; + + // maxHeapifyLeonardoTree(rightChildIndex, currentLeonardoLevel - 2, array); + // maxHeapifyLeonardoTree(leftChildIndex, currentLeonardoLevel - 1, array); + + if (array[rightChildIndex].compareTo(array[leftChildIndex]) >= 0) { + childIndexForSwap = rightChildIndex; + } else { + childIndexForSwap = leftChildIndex; + } + + if (array[childIndexForSwap].compareTo(array[currentRootNodeIndex]) > 0) { + // swap(And keep on swapping I guess, I did not implement that which might be causing issue?) + swap(array, currentRootNodeIndex, childIndexForSwap); + if (childIndexForSwap == rightChildIndex) { + maxHeapifyLeonardoTree(rightChildIndex, currentLeonardoLevel - 2, array); + } else { // swap happened with the left child + maxHeapifyLeonardoTree(leftChildIndex, currentLeonardoLevel - 1, array); } } - return array; + } + + @Override + public > T[] sort(T[] unsorted) { + // TODO Auto-generated method stub + smoothSort(unsorted); + return unsorted; } } diff --git a/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java b/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java deleted file mode 100644 index 3ef720519c1d..000000000000 --- a/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.thealgorithms.sorts; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; - -import org.junit.jupiter.api.Test; - -public class SmoothSortTest { - - @Test - public void smoothSortSingleIntegerArray() { - Integer[] inputArray = {4}; - Integer[] outputArray = SmoothSort.smoothSort(inputArray); - Integer[] expectedOutput = {4}; - assertArrayEquals(outputArray, expectedOutput); - } - - @Test - public void smoothSortNonDuplicateIntegerArray() { - Integer[] inputArray = {6, 1, 99, 27, 15, 23, 36}; - Integer[] outputArray = SmoothSort.smoothSort(inputArray); - Integer[] expectedOutput = {1, 6, 15, 23, 27, 36, 99}; - assertArrayEquals(outputArray, expectedOutput); - } - - @Test - public void smoothSortDuplicateIntegerArray() { - Integer[] inputArray = {6, 1, 27, 15, 23, 27, 36, 23}; - Integer[] outputArray = SmoothSort.smoothSort(inputArray); - Integer[] expectedOutput = {1, 6, 15, 23, 23, 27, 27, 36}; - assertArrayEquals(outputArray, expectedOutput); - } - - @Test - public void smoothSortNonDuplicateIntegerArrayWithNegativeNum() { - Integer[] inputArray = {6, -1, 99, 27, -15, 23, -36}; - Integer[] outputArray = SmoothSort.smoothSort(inputArray); - Integer[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99}; - assertArrayEquals(outputArray, expectedOutput); - } - - @Test - public void smoothSortDuplicateIntegerArrayWithNegativeNum() { - Integer[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23}; - Integer[] outputArray = SmoothSort.smoothSort(inputArray); - Integer[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27}; - assertArrayEquals(outputArray, expectedOutput); - } -} From 990b1839e90e5795c4b1700b7fee1495ca7167b0 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Mon, 24 Jun 2024 18:21:28 +0530 Subject: [PATCH 11/32] Forgot to add test file --- src/test/java/com/thealgorithms/sorts/SmoothSortTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/test/java/com/thealgorithms/sorts/SmoothSortTest.java diff --git a/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java b/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java new file mode 100644 index 000000000000..8df0502e80e7 --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/SmoothSortTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +public class SmoothSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new SmoothSort(); + } +} From 0eda98e2a34ed8735adb10cb7a158d479dcca9a0 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Mon, 24 Jun 2024 18:37:20 +0530 Subject: [PATCH 12/32] Improved code coverage yo 99.9% --- src/main/java/com/thealgorithms/sorts/SmoothSort.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 93566c8847bb..4cc613b1a092 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -172,9 +172,6 @@ private static > void shiftRootAndRestoreHeap(int lenard maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); break; } - - currentRootNodeIndex = rootNodeIndices.get(j); - prevRootNodeIndex = rootNodeIndices.get(j - 1); } } From aed3358afe175ece6e16eea0809eda311f588098 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Mon, 24 Jun 2024 18:51:32 +0530 Subject: [PATCH 13/32] Removed the break statement to improve code coverage. --- src/main/java/com/thealgorithms/sorts/SmoothSort.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 4cc613b1a092..063b05de41e2 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -170,7 +170,6 @@ private static > void shiftRootAndRestoreHeap(int lenard j = j - 1; if (j == i - 1) { maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); - break; } } } From ab905bf392ddd3a2a13de40697d8921825935aa2 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Tue, 25 Jun 2024 17:09:15 +0530 Subject: [PATCH 14/32] Removed comments and used SortUtils --- .../com/thealgorithms/sorts/SmoothSort.java | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 063b05de41e2..244b36b3f0b7 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -155,15 +155,14 @@ private static > void shiftRootAndRestoreHeap(int lenard int indexOfRightChild = rootNodeIndices.get(j) - 1; // right child is of level n-2 int indexOfLeftChild = rootNodeIndices.get(j) - 1 - getLeonardoNumbers()[currentLeonardoLevel - 2]; if (array[prevRootNodeIndex].compareTo(array[indexOfRightChild]) > 0 && array[prevRootNodeIndex].compareTo(array[indexOfLeftChild]) > 0) { - swap(array, prevRootNodeIndex, currentRootNodeIndex); + SortUtils.swap(array, prevRootNodeIndex, currentRootNodeIndex); rootNodeIndexForHeapify = prevRootNodeIndex; leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; } else { maxHeapifyLeonardoTree(currentRootNodeIndex, currentLeonardoLevel, array); } } else { - // swap - swap(array, prevRootNodeIndex, currentRootNodeIndex); + SortUtils.swap(array, prevRootNodeIndex, currentRootNodeIndex); rootNodeIndexForHeapify = prevRootNodeIndex; leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; } @@ -174,13 +173,7 @@ private static > void shiftRootAndRestoreHeap(int lenard } } - maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); // for the last tree if needed - } - - private static void swap(T[] array, int idx, int idy) { - T swap = array[idx]; - array[idx] = array[idy]; - array[idy] = swap; + maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); } private static > void maxHeapifyLeonardoTree(int rootNodeIndex, int currentLeonardoLevel, T[] array) { @@ -198,9 +191,6 @@ private static > void maxHeapifyLeonardoTree(int rootNod int leftChildIndex = rootNodeIndex - getLeonardoNumbers()[currentLeonardoLevel - 2] - 1; int childIndexForSwap = -1; - // maxHeapifyLeonardoTree(rightChildIndex, currentLeonardoLevel - 2, array); - // maxHeapifyLeonardoTree(leftChildIndex, currentLeonardoLevel - 1, array); - if (array[rightChildIndex].compareTo(array[leftChildIndex]) >= 0) { childIndexForSwap = rightChildIndex; } else { @@ -208,8 +198,7 @@ private static > void maxHeapifyLeonardoTree(int rootNod } if (array[childIndexForSwap].compareTo(array[currentRootNodeIndex]) > 0) { - // swap(And keep on swapping I guess, I did not implement that which might be causing issue?) - swap(array, currentRootNodeIndex, childIndexForSwap); + SortUtils.swap(array, currentRootNodeIndex, childIndexForSwap); if (childIndexForSwap == rightChildIndex) { maxHeapifyLeonardoTree(rightChildIndex, currentLeonardoLevel - 2, array); } else { // swap happened with the left child @@ -220,7 +209,6 @@ private static > void maxHeapifyLeonardoTree(int rootNod @Override public > T[] sort(T[] unsorted) { - // TODO Auto-generated method stub smoothSort(unsorted); return unsorted; } From ec02a6cf5ff64c8cdbe803d8835f3b55b661a883 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Wed, 26 Jun 2024 16:43:01 +0530 Subject: [PATCH 15/32] Use SingleBitOperations class. --- .../java/com/thealgorithms/sorts/SmoothSort.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 244b36b3f0b7..a821bf8bb58b 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -4,6 +4,8 @@ import java.util.Arrays; import java.util.Collections; +import com.thealgorithms.bitmanipulation.SingleBitOperations; + /** * Wikipedia: https://en.wikipedia.org/wiki/Smoothsort */ @@ -34,9 +36,9 @@ private static > void smoothSort(T[] array) { Integer[] consecutiveTreeIndices = findConsecutiveLeonardoTreeIndices(leonardoLevelTracker); if (consecutiveTreeIndices[0] != -1) { // if 0th or 1st index is -1 that implies there are no concequtive trees - leonardoLevelTracker = leonardoLevelTracker & ~(1 << consecutiveTreeIndices[0]); - leonardoLevelTracker = leonardoLevelTracker & ~(1 << consecutiveTreeIndices[1]); - leonardoLevelTracker = leonardoLevelTracker | (1 << consecutiveTreeIndices[1] + 1); + leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices[0]); + leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices[1]); + leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, consecutiveTreeIndices[1] + 1); } else if ((leonardoLevelTracker & 2) == 0) { leonardoLevelTracker = leonardoLevelTracker | (1 << 1); } else { @@ -54,10 +56,10 @@ private static > void smoothSort(T[] array) { int lastTreeLevel = getRightMostTree(leonardoLevelTracker); // getting the right most tree - leonardoLevelTracker = leonardoLevelTracker & ~(1 << lastTreeLevel); + leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, lastTreeLevel); if (lastTreeLevel != 0 && lastTreeLevel != 1) { - leonardoLevelTracker = leonardoLevelTracker | (1 << lastTreeLevel - 1); - leonardoLevelTracker = leonardoLevelTracker | (1 << lastTreeLevel - 2); + leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, lastTreeLevel - 1); + leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, lastTreeLevel - 2); } leonardoHeapSize--; From b19bd38a02609421c248eb0edde6db57f0920583 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Fri, 28 Jun 2024 14:44:48 +0530 Subject: [PATCH 16/32] Conditional changes on when to call max_heapify. --- .../com/thealgorithms/sorts/SmoothSort.java | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index a821bf8bb58b..bdd959dd8d76 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -140,11 +140,13 @@ private static > void shiftRootAndRestoreHeap(int lenard int rootNodeIndexForHeapify = rootNodeIndices.getLast(); int leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[currentLeonardoTreeLevels.length - 1]; + boolean swaped =false; + // if(rootNodeIndices.size() == 1) { + // maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); + // return; + // } - for (int i = 0; i < rootNodeIndices.size(); i++) { - if (i == 0) { - continue; - } + for (int i = 1; i < rootNodeIndices.size(); i++) { int currentRootNodeIndex = rootNodeIndices.get(i); int prevRootNodeIndex = rootNodeIndices.get(i - 1); @@ -160,22 +162,37 @@ private static > void shiftRootAndRestoreHeap(int lenard SortUtils.swap(array, prevRootNodeIndex, currentRootNodeIndex); rootNodeIndexForHeapify = prevRootNodeIndex; leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; + swaped = true; } else { maxHeapifyLeonardoTree(currentRootNodeIndex, currentLeonardoLevel, array); + swaped = false; } } else { SortUtils.swap(array, prevRootNodeIndex, currentRootNodeIndex); rootNodeIndexForHeapify = prevRootNodeIndex; leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; + swaped = true; } j = j - 1; - if (j == i - 1) { - maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); + if(j > 0) { + currentRootNodeIndex = rootNodeIndices.get(j); + prevRootNodeIndex = rootNodeIndices.get(j - 1); + } + else{ + // j = 0 reached the left most tree + break; } } + + if(swaped) { + maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); + swaped = false; + } + } - maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); + maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); // In case of insert and no swap. + } private static > void maxHeapifyLeonardoTree(int rootNodeIndex, int currentLeonardoLevel, T[] array) { @@ -208,7 +225,16 @@ private static > void maxHeapifyLeonardoTree(int rootNod } } } - + public static void main(String args[]) { + // This is an example + + Integer[] array = new Integer[] { + 64,43,67,56,84,50,46,27,78,99,99,9,34,92 + }; + + smoothSort(array); + System.out.println(SortUtils.isSorted(array)); + } @Override public > T[] sort(T[] unsorted) { smoothSort(unsorted); From 5d21701f52cf3118856c6853c70e74ddfb9d0209 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Sat, 29 Jun 2024 17:00:20 +0530 Subject: [PATCH 17/32] Skeleton of LeonardoHeap.java --- src/main/java/com/thealgorithms/sorts/SmoothSort.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index bdd959dd8d76..7ac92fa2dd85 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -141,10 +141,6 @@ private static > void shiftRootAndRestoreHeap(int lenard int rootNodeIndexForHeapify = rootNodeIndices.getLast(); int leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[currentLeonardoTreeLevels.length - 1]; boolean swaped =false; - // if(rootNodeIndices.size() == 1) { - // maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); - // return; - // } for (int i = 1; i < rootNodeIndices.size(); i++) { From 951653ff8ccac41c588ca306cf4e5edf2ad3e3f8 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Thu, 4 Jul 2024 12:59:06 +0530 Subject: [PATCH 18/32] Leonardo Heap implementeaton , TODO: Test cases --- .../datastructures/heaps/LeonardoHeap.java | 243 ++++++++++++++++++ .../com/thealgorithms/sorts/SmoothSort.java | 216 +--------------- 2 files changed, 250 insertions(+), 209 deletions(-) create mode 100644 src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java new file mode 100644 index 000000000000..ca8804242a33 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java @@ -0,0 +1,243 @@ +package com.thealgorithms.datastructures.heaps; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import com.thealgorithms.bitmanipulation.SingleBitOperations; +import com.thealgorithms.maths.LeonardoNumber; + +public class LeonardoHeap> { + + private int leonardoLevelTracker; + private int leonardoHeapSize; + private final List leonardoHeap; + + public LeonardoHeap() { + this.leonardoHeap = new ArrayList(); + this.leonardoLevelTracker = 0; + this.leonardoHeapSize = 0; + } + + public static Integer[] getLeonardoNumbers() { + Integer[] leonardoNumbers = {1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891, 35421, 57313, 92735, 150049, 242785, 392835, 635621, 1028457, 1664079, 2692537, 4356617, 7049155, 1405773, 18454929, 29860703, 48315633, 78176337, 126491971, + 204668309, 331160281, 535828591}; + + return leonardoNumbers; + } + + public int getHeapsize() { + return this.leonardoHeapSize; + } + + private void decreaseLeonardoLevelTracker() { + int lastTreeLevel = getRightMostTree(); + leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, lastTreeLevel); + if (lastTreeLevel != 0 && lastTreeLevel != 1) { + leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, lastTreeLevel - 1); + leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, lastTreeLevel - 2); + } + } + + private void increaseLeonardoLevelTracker() { + Integer[] consecutiveTreeIndices = findConsecutiveLeonardoTreeIndices(leonardoLevelTracker); + if (consecutiveTreeIndices[0] != -1) { + // if 0th or 1st index is -1 that implies there are no concequtive trees + leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices[0]); + leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices[1]); + leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, consecutiveTreeIndices[1] + 1); + } else if ((leonardoLevelTracker & 2) == 0) { + leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, 1); + } else { + leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, 0); + } + } + + private void decreaseHeapSize() { + this.leonardoHeapSize--; + } + + private void increaseHeapSize() { + this.leonardoHeapSize++; + } + + private void maxHeapifyLeonardoTree(int rootNodeIndex, int currentLeonardoLevel) { + // A leonardo tree of level n is just 1 node(the root) plus the leonardo tree of n-1 level(left child) plus leonardo tree of n-2 level(right child) + // To maxheapify a leonardo tree we need to compare the current root and roots of it's left and right subtree + // We recursively hepify the left and right subtrees using the currentLeonardoLevel + + // BASE CASE + if (currentLeonardoLevel == 0 || currentLeonardoLevel == 1) { + return; // Trees with one node are in already max-heapified. + } + + int currentRootNodeIndex = rootNodeIndex; + int rightChildIndex = rootNodeIndex - 1; + int leftChildIndex = rootNodeIndex - LeonardoNumber.leonardoNumber(currentLeonardoLevel - 2) - 1; + int childIndexForSwap = -1; + + if (leonardoHeap.get(rightChildIndex).compareTo(leonardoHeap.get(leftChildIndex)) >= 0) { + childIndexForSwap = rightChildIndex; + } else { + childIndexForSwap = leftChildIndex; + } + + if (leonardoHeap.get(childIndexForSwap).compareTo(leonardoHeap.get(currentRootNodeIndex)) > 0) { + swap(currentRootNodeIndex, childIndexForSwap); + if (childIndexForSwap == rightChildIndex) { + maxHeapifyLeonardoTree(rightChildIndex, currentLeonardoLevel - 2); + } else { // swap happened with the left child + maxHeapifyLeonardoTree(leftChildIndex, currentLeonardoLevel - 1); + } + } + } + + private void shiftRootAndRestoreHeap() { + + if (getHeapsize() == 0) { + return; + } + + Integer[] currentLeonardoTreeLevels = findAllLeonardoTreeIndices(); + int previousTreeSizeCumulative = 0; + ArrayList rootNodeIndices = new ArrayList(); + Collections.reverse(Arrays.asList(currentLeonardoTreeLevels)); // To get the Levels in decreasing order of levels + + // The number of roots are going to be same the the number of levels + // iterate over the currentLeonardoTreeLevels and get roots + + for (int i = 0; i < currentLeonardoTreeLevels.length; i++) { + rootNodeIndices.add(previousTreeSizeCumulative + LeonardoNumber.leonardoNumber(currentLeonardoTreeLevels[i]) - 1); + previousTreeSizeCumulative = previousTreeSizeCumulative + LeonardoNumber.leonardoNumber(currentLeonardoTreeLevels[i]); + } + + int rootNodeIndexForHeapify = rootNodeIndices.getLast(); + int leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[currentLeonardoTreeLevels.length - 1]; + boolean swaped =false; + + for (int i = 1; i < rootNodeIndices.size(); i++) { + + int currentRootNodeIndex = rootNodeIndices.get(i); + int prevRootNodeIndex = rootNodeIndices.get(i - 1); + int j = i; + while (leonardoHeap.get(prevRootNodeIndex).compareTo(leonardoHeap.get(currentRootNodeIndex)) > 0) { + int currentLeonardoLevel = currentLeonardoTreeLevels[j]; + if (currentLeonardoLevel > 1) { + // compare child and swap + + int indexOfRightChild = rootNodeIndices.get(j) - 1; // right child is of level n-2 + int indexOfLeftChild = rootNodeIndices.get(j) - 1 - LeonardoNumber.leonardoNumber(currentLeonardoLevel - 2); + if (leonardoHeap.get(prevRootNodeIndex).compareTo(leonardoHeap.get(indexOfRightChild)) > 0 && leonardoHeap.get(prevRootNodeIndex).compareTo(leonardoHeap.get(indexOfLeftChild)) > 0) { + swap(prevRootNodeIndex, currentRootNodeIndex); + rootNodeIndexForHeapify = prevRootNodeIndex; + leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; + swaped = true; + } else { + maxHeapifyLeonardoTree(currentRootNodeIndex, currentLeonardoLevel); + swaped = false; + } + } else { + swap(prevRootNodeIndex, currentRootNodeIndex); + rootNodeIndexForHeapify = prevRootNodeIndex; + leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; + swaped = true; + } + j = j - 1; + if(j > 0) { + currentRootNodeIndex = rootNodeIndices.get(j); + prevRootNodeIndex = rootNodeIndices.get(j - 1); + } + else{ + // j = 0 reached the left most tree + break; + } + } + + if(swaped) { + maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify); + swaped = false; + } + + } + + maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify); // In case of insert and no swap. + + } + + private int getRightMostTree() { + // Isolate the rightmost set bit + int isolatedBit = leonardoLevelTracker & -leonardoLevelTracker; + int position = 0; + + while (isolatedBit > 1) { + isolatedBit >>= 1; + position++; + } + + return position; + } + + private static Integer[] findConsecutiveLeonardoTreeIndices(int num) { + int prevOneIndex = -1; + int currentLevel; + + Integer[] answer = new Integer[] {-1, -1}; + for (int i = 0; num > 0; i++) { + currentLevel = num & 1; + if (currentLevel == 1) { + if (prevOneIndex != -1) { + answer[0] = prevOneIndex; + answer[1] = i; + } + prevOneIndex = i; + } else { + prevOneIndex = -1; + } + num >>>= 1; + } + return answer; + } + + private void swap(int i, int j) { + T temp = leonardoHeap.get(i); + leonardoHeap.set(i, leonardoHeap.get(j)); + leonardoHeap.set(j, temp); + } + + // TODO use lists + private Integer[] findAllLeonardoTreeIndices() { + int setBitCount = 0; + for (int i = 0; i < Integer.SIZE; i++) { + if ((leonardoLevelTracker & (1 << i)) != 0) { + setBitCount++; + } + } + + Integer[] setBitIndexes = new Integer[setBitCount]; + int index = 0; + for (int i = 0; i < Integer.SIZE; i++) { + if ((leonardoLevelTracker & (1 << i)) != 0) { + setBitIndexes[index++] = i; + } + } + return setBitIndexes; + } + + + public void insertElement(T element) { + increaseLeonardoLevelTracker(); + leonardoHeap.add(element); + increaseHeapSize(); + shiftRootAndRestoreHeap(); + } + + public T deleteElement() { + decreaseLeonardoLevelTracker(); + decreaseHeapSize(); + T element = leonardoHeap.removeLast(); + shiftRootAndRestoreHeap(); + + return element; + } +} diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 7ac92fa2dd85..8606ea80246d 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -5,6 +5,7 @@ import java.util.Collections; import com.thealgorithms.bitmanipulation.SingleBitOperations; +import com.thealgorithms.datastructures.heaps.LeonardoHeap; /** * Wikipedia: https://en.wikipedia.org/wiki/Smoothsort @@ -14,223 +15,20 @@ public final class SmoothSort implements SortAlgorithm { public SmoothSort() { } - private static Integer[] getLeonardoNumbers() { - Integer[] leonardoNumbers = {1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891, 35421, 57313, 92735, 150049, 242785, 392835, 635621, 1028457, 1664079, 2692537, 4356617, 7049155, 1405773, 18454929, 29860703, 48315633, 78176337, 126491971, - 204668309, 331160281, 535828591}; - - return leonardoNumbers; - } - private static > void smoothSort(T[] array) { int length = array.length; - int leonardoHeapSize = 0; // start with size 0 - int leonardoLevelTracker = 0; // No leonardo tree present initially - - while (leonardoHeapSize < length) { - // if two trees with consequtive level - // combine them to get new tree - // else if there is no Level 1, add the node as level 1 - // else add the node as Level 0 - // perform shiftRoot and restore heap property - - Integer[] consecutiveTreeIndices = findConsecutiveLeonardoTreeIndices(leonardoLevelTracker); - if (consecutiveTreeIndices[0] != -1) { - // if 0th or 1st index is -1 that implies there are no concequtive trees - leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices[0]); - leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices[1]); - leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, consecutiveTreeIndices[1] + 1); - } else if ((leonardoLevelTracker & 2) == 0) { - leonardoLevelTracker = leonardoLevelTracker | (1 << 1); - } else { - leonardoLevelTracker = leonardoLevelTracker | (1 << 0); - } - leonardoHeapSize++; - shiftRootAndRestoreHeap(leonardoLevelTracker, leonardoHeapSize, array); - } + LeonardoHeap leonardoHeap = new LeonardoHeap(); - while (leonardoHeapSize > 0) { - // destroy the current level - // if level is not L1 or L0 - // create two smaller sublevels - // perform shiftRoot and restore heap property - - int lastTreeLevel = getRightMostTree(leonardoLevelTracker); // getting the right most tree - - leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, lastTreeLevel); - if (lastTreeLevel != 0 && lastTreeLevel != 1) { - leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, lastTreeLevel - 1); - leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, lastTreeLevel - 2); - } - - leonardoHeapSize--; - shiftRootAndRestoreHeap(leonardoLevelTracker, leonardoHeapSize, array); + for(int i = 0; i < length ; i++) { + leonardoHeap.insertElement(array[i]); } - } - - private static int getRightMostTree(int leonardoLevelTracker) { - // Isolate the rightmost set bit - int isolatedBit = leonardoLevelTracker & -leonardoLevelTracker; - int position = 0; - while (isolatedBit > 1) { - isolatedBit >>= 1; - position++; + for(int i = 0; i < length; i++) { + T maxElement = leonardoHeap.deleteElement(); + array[length - i - 1] = maxElement; } - - return position; } - private static Integer[] findConsecutiveLeonardoTreeIndices(int num) { - int prevOneIndex = -1; - int currentLevel; - - Integer[] answer = new Integer[] {-1, -1}; - for (int i = 0; num > 0; i++) { - currentLevel = num & 1; - if (currentLevel == 1) { - if (prevOneIndex != -1) { - answer[0] = prevOneIndex; - answer[1] = i; - } - prevOneIndex = i; - } else { - prevOneIndex = -1; - } - num >>>= 1; - } - return answer; - } - - private static Integer[] findAllLeonardoTreeIndices(int num) { - int setBitCount = 0; - for (int i = 0; i < Integer.SIZE; i++) { - if ((num & (1 << i)) != 0) { - setBitCount++; - } - } - - Integer[] setBitIndexes = new Integer[setBitCount]; - int index = 0; - for (int i = 0; i < Integer.SIZE; i++) { - if ((num & (1 << i)) != 0) { - setBitIndexes[index++] = i; - } - } - return setBitIndexes; - } - - private static > void shiftRootAndRestoreHeap(int lenardoLevelTracker, int leonardoHeapSize, T[] array) { - - if (leonardoHeapSize == 0) { - return; - } - - Integer[] currentLeonardoTreeLevels = findAllLeonardoTreeIndices(lenardoLevelTracker); - int previousTreeSizeCumulative = 0; - ArrayList rootNodeIndices = new ArrayList(); - Collections.reverse(Arrays.asList(currentLeonardoTreeLevels)); // To get the Levels in decreasing order of levels - - // The number of roots are going to be same the the number of levels - // iterate over the currentLeonardoTreeLevels and get roots - - for (int i = 0; i < currentLeonardoTreeLevels.length; i++) { - rootNodeIndices.add(previousTreeSizeCumulative + getLeonardoNumbers()[currentLeonardoTreeLevels[i]] - 1); - previousTreeSizeCumulative = previousTreeSizeCumulative + getLeonardoNumbers()[currentLeonardoTreeLevels[i]]; - } - - int rootNodeIndexForHeapify = rootNodeIndices.getLast(); - int leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[currentLeonardoTreeLevels.length - 1]; - boolean swaped =false; - - for (int i = 1; i < rootNodeIndices.size(); i++) { - - int currentRootNodeIndex = rootNodeIndices.get(i); - int prevRootNodeIndex = rootNodeIndices.get(i - 1); - int j = i; - while (array[prevRootNodeIndex].compareTo(array[currentRootNodeIndex]) > 0) { - int currentLeonardoLevel = currentLeonardoTreeLevels[j]; - if (currentLeonardoLevel > 1) { - // compare child and swap - - int indexOfRightChild = rootNodeIndices.get(j) - 1; // right child is of level n-2 - int indexOfLeftChild = rootNodeIndices.get(j) - 1 - getLeonardoNumbers()[currentLeonardoLevel - 2]; - if (array[prevRootNodeIndex].compareTo(array[indexOfRightChild]) > 0 && array[prevRootNodeIndex].compareTo(array[indexOfLeftChild]) > 0) { - SortUtils.swap(array, prevRootNodeIndex, currentRootNodeIndex); - rootNodeIndexForHeapify = prevRootNodeIndex; - leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; - swaped = true; - } else { - maxHeapifyLeonardoTree(currentRootNodeIndex, currentLeonardoLevel, array); - swaped = false; - } - } else { - SortUtils.swap(array, prevRootNodeIndex, currentRootNodeIndex); - rootNodeIndexForHeapify = prevRootNodeIndex; - leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; - swaped = true; - } - j = j - 1; - if(j > 0) { - currentRootNodeIndex = rootNodeIndices.get(j); - prevRootNodeIndex = rootNodeIndices.get(j - 1); - } - else{ - // j = 0 reached the left most tree - break; - } - } - - if(swaped) { - maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); - swaped = false; - } - - } - - maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify, array); // In case of insert and no swap. - - } - - private static > void maxHeapifyLeonardoTree(int rootNodeIndex, int currentLeonardoLevel, T[] array) { - // A leonardo tree of level n is just 1 node(the root) plus the leonardo tree of n-1 level(left child) plus leonardo tree of n-2 level(right child) - // To maxheapify a leonardo tree we need to compare the current root and roots of it's left and right subtree - // We recursively hepify the left and right subtrees using the currentLeonardoLevel - - // BASE CASE - if (currentLeonardoLevel == 0 || currentLeonardoLevel == 1) { - return; // Trees with one node are in already max-heapified. - } - - int currentRootNodeIndex = rootNodeIndex; - int rightChildIndex = rootNodeIndex - 1; - int leftChildIndex = rootNodeIndex - getLeonardoNumbers()[currentLeonardoLevel - 2] - 1; - int childIndexForSwap = -1; - - if (array[rightChildIndex].compareTo(array[leftChildIndex]) >= 0) { - childIndexForSwap = rightChildIndex; - } else { - childIndexForSwap = leftChildIndex; - } - - if (array[childIndexForSwap].compareTo(array[currentRootNodeIndex]) > 0) { - SortUtils.swap(array, currentRootNodeIndex, childIndexForSwap); - if (childIndexForSwap == rightChildIndex) { - maxHeapifyLeonardoTree(rightChildIndex, currentLeonardoLevel - 2, array); - } else { // swap happened with the left child - maxHeapifyLeonardoTree(leftChildIndex, currentLeonardoLevel - 1, array); - } - } - } - public static void main(String args[]) { - // This is an example - - Integer[] array = new Integer[] { - 64,43,67,56,84,50,46,27,78,99,99,9,34,92 - }; - - smoothSort(array); - System.out.println(SortUtils.isSorted(array)); - } @Override public > T[] sort(T[] unsorted) { smoothSort(unsorted); From 79a5d20c3f0b6029312b8bab2ac0e422e9ca0519 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Fri, 5 Jul 2024 19:57:20 +0530 Subject: [PATCH 19/32] Slight modifications to code --- .../datastructures/heaps/LeonardoHeap.java | 78 +++++++------------ .../com/thealgorithms/sorts/SmoothSort.java | 13 +--- 2 files changed, 34 insertions(+), 57 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java index ca8804242a33..a4c1d6f62623 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java @@ -1,18 +1,18 @@ package com.thealgorithms.datastructures.heaps; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import com.thealgorithms.bitmanipulation.SingleBitOperations; import com.thealgorithms.maths.LeonardoNumber; +import java.util.ArrayList; +import java.util.List; +/** + * Wikipedia: https://en.wikipedia.org/wiki/Smoothsort + */ public class LeonardoHeap> { private int leonardoLevelTracker; private int leonardoHeapSize; - private final List leonardoHeap; + private final List leonardoHeap; public LeonardoHeap() { this.leonardoHeap = new ArrayList(); @@ -20,13 +20,6 @@ public LeonardoHeap() { this.leonardoHeapSize = 0; } - public static Integer[] getLeonardoNumbers() { - Integer[] leonardoNumbers = {1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891, 35421, 57313, 92735, 150049, 242785, 392835, 635621, 1028457, 1664079, 2692537, 4356617, 7049155, 1405773, 18454929, 29860703, 48315633, 78176337, 126491971, - 204668309, 331160281, 535828591}; - - return leonardoNumbers; - } - public int getHeapsize() { return this.leonardoHeapSize; } @@ -41,12 +34,12 @@ private void decreaseLeonardoLevelTracker() { } private void increaseLeonardoLevelTracker() { - Integer[] consecutiveTreeIndices = findConsecutiveLeonardoTreeIndices(leonardoLevelTracker); - if (consecutiveTreeIndices[0] != -1) { + ArrayList consecutiveTreeIndices = findConsecutiveLeonardoTreeIndices(leonardoLevelTracker); + if (consecutiveTreeIndices.get(0) != -1) { // if 0th or 1st index is -1 that implies there are no concequtive trees - leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices[0]); - leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices[1]); - leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, consecutiveTreeIndices[1] + 1); + leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices.get(0)); + leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices.get(1)); + leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, consecutiveTreeIndices.get(1) + 1); } else if ((leonardoLevelTracker & 2) == 0) { leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, 1); } else { @@ -102,7 +95,6 @@ private void shiftRootAndRestoreHeap() { Integer[] currentLeonardoTreeLevels = findAllLeonardoTreeIndices(); int previousTreeSizeCumulative = 0; ArrayList rootNodeIndices = new ArrayList(); - Collections.reverse(Arrays.asList(currentLeonardoTreeLevels)); // To get the Levels in decreasing order of levels // The number of roots are going to be same the the number of levels // iterate over the currentLeonardoTreeLevels and get roots @@ -114,7 +106,7 @@ private void shiftRootAndRestoreHeap() { int rootNodeIndexForHeapify = rootNodeIndices.getLast(); int leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[currentLeonardoTreeLevels.length - 1]; - boolean swaped =false; + boolean swaped = false; for (int i = 1; i < rootNodeIndices.size(); i++) { @@ -144,27 +136,24 @@ private void shiftRootAndRestoreHeap() { swaped = true; } j = j - 1; - if(j > 0) { + if (j > 0) { currentRootNodeIndex = rootNodeIndices.get(j); prevRootNodeIndex = rootNodeIndices.get(j - 1); - } - else{ + } else { // j = 0 reached the left most tree break; } } - - if(swaped) { + + if (swaped) { maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify); swaped = false; } - } maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify); // In case of insert and no swap. - } - + private int getRightMostTree() { // Isolate the rightmost set bit int isolatedBit = leonardoLevelTracker & -leonardoLevelTracker; @@ -178,17 +167,20 @@ private int getRightMostTree() { return position; } - private static Integer[] findConsecutiveLeonardoTreeIndices(int num) { + private static ArrayList findConsecutiveLeonardoTreeIndices(int num) { int prevOneIndex = -1; int currentLevel; - Integer[] answer = new Integer[] {-1, -1}; + ArrayList answer = new ArrayList(); + answer.add(-1); + answer.add(-1); + for (int i = 0; num > 0; i++) { currentLevel = num & 1; if (currentLevel == 1) { if (prevOneIndex != -1) { - answer[0] = prevOneIndex; - answer[1] = i; + answer.set(0, prevOneIndex); + answer.set(1, i); } prevOneIndex = i; } else { @@ -205,34 +197,24 @@ private void swap(int i, int j) { leonardoHeap.set(j, temp); } - // TODO use lists private Integer[] findAllLeonardoTreeIndices() { - int setBitCount = 0; - for (int i = 0; i < Integer.SIZE; i++) { - if ((leonardoLevelTracker & (1 << i)) != 0) { - setBitCount++; - } - } - - Integer[] setBitIndexes = new Integer[setBitCount]; - int index = 0; - for (int i = 0; i < Integer.SIZE; i++) { + List setBitIndexes = new ArrayList<>(); + for (int i = Integer.SIZE - 1; i >= 0; i--) { if ((leonardoLevelTracker & (1 << i)) != 0) { - setBitIndexes[index++] = i; + setBitIndexes.add(i); } } - return setBitIndexes; + return setBitIndexes.toArray(new Integer[0]); } - - public void insertElement(T element) { + public void addElement(T element) { increaseLeonardoLevelTracker(); leonardoHeap.add(element); increaseHeapSize(); shiftRootAndRestoreHeap(); } - public T deleteElement() { + public T removeElement() { decreaseLeonardoLevelTracker(); decreaseHeapSize(); T element = leonardoHeap.removeLast(); diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 8606ea80246d..d8b3e5799b79 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -1,10 +1,5 @@ package com.thealgorithms.sorts; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; - -import com.thealgorithms.bitmanipulation.SingleBitOperations; import com.thealgorithms.datastructures.heaps.LeonardoHeap; /** @@ -19,12 +14,12 @@ private static > void smoothSort(T[] array) { int length = array.length; LeonardoHeap leonardoHeap = new LeonardoHeap(); - for(int i = 0; i < length ; i++) { - leonardoHeap.insertElement(array[i]); + for (int i = 0; i < length; i++) { + leonardoHeap.addElement(array[i]); } - for(int i = 0; i < length; i++) { - T maxElement = leonardoHeap.deleteElement(); + for (int i = 0; i < length; i++) { + T maxElement = leonardoHeap.removeElement(); array[length - i - 1] = maxElement; } } From 645b29c44bfbfd88dcf06566389b89b14cbf26e3 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Mon, 8 Jul 2024 11:47:35 +0530 Subject: [PATCH 20/32] variable name modifications. --- .../java/com/thealgorithms/sorts/SmoothSort.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index d8b3e5799b79..77c737a05a0e 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -11,22 +11,21 @@ public SmoothSort() { } private static > void smoothSort(T[] array) { - int length = array.length; LeonardoHeap leonardoHeap = new LeonardoHeap(); - for (int i = 0; i < length; i++) { + for (int i = 0; i < array.length; i++) { leonardoHeap.addElement(array[i]); } - for (int i = 0; i < length; i++) { - T maxElement = leonardoHeap.removeElement(); - array[length - i - 1] = maxElement; + for (int i = 0; i < array.length; i++) { + final T maxElement = leonardoHeap.removeElement(); + array[array.length - i - 1] = maxElement; } } @Override - public > T[] sort(T[] unsorted) { - smoothSort(unsorted); - return unsorted; + public > T[] sort(T[] array) { + smoothSort(array); + return array; } } From 1adbd15d38a073e57407eb748202523968c5712e Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Mon, 8 Jul 2024 14:19:59 +0530 Subject: [PATCH 21/32] Added LeonardoHeapTest.java --- .../heaps/LeonardoHeapTest.java | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java diff --git a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java new file mode 100644 index 000000000000..eda624af944d --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java @@ -0,0 +1,97 @@ +package com.thealgorithms.datastructures.heaps; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +public class LeonardoHeapTest { + + @Test + public > void testEmpty() { + LeonardoHeap heap = new LeonardoHeap(); + assertEquals(0, heap.getHeapsize()); + } + + @Test + public > void testAddElement() { + LeonardoHeap heap = new LeonardoHeap<>(); + heap.addElement(5); + heap.addElement(3); + heap.addElement(8); + + assertEquals(3, heap.getHeapsize()); + assertEquals(8, heap.removeElement()); // Max element should be 8 + } + + @Test + public void testRemoveElement() { + LeonardoHeap heap = new LeonardoHeap<>(); + heap.addElement(10); + heap.addElement(20); + heap.addElement(5); + + assertEquals(20, heap.removeElement()); + assertEquals(10, heap.removeElement()); + assertEquals(5, heap.removeElement()); + } + + @Test + public void testHeapSize() { + LeonardoHeap heap = new LeonardoHeap<>(); + assertEquals(0, heap.getHeapsize()); + + heap.addElement(1); + assertEquals(1, heap.getHeapsize()); + + heap.addElement(2); + assertEquals(2, heap.getHeapsize()); + + heap.removeElement(); + assertEquals(1, heap.getHeapsize()); + + heap.removeElement(); + assertEquals(0, heap.getHeapsize()); + } + + @Test + public > void testAddElementStrings() { + LeonardoHeap heap = new LeonardoHeap(); + heap.addElement("z"); + heap.addElement("a"); + heap.addElement("x"); + heap.addElement("b"); + heap.addElement("y"); + + assertEquals(5, heap.getHeapsize()); + assertEquals("z", heap.removeElement()); // Max element should be 8 + } + + @Test + public void testRemoveElementString() { + LeonardoHeap heap = new LeonardoHeap(); + heap.addElement("z"); + heap.addElement("a"); + heap.addElement("x"); + + assertEquals("z", heap.removeElement()); + assertEquals("x", heap.removeElement()); + assertEquals("a", heap.removeElement()); + } + + @Test + public void testHeapSizeString() { + LeonardoHeap heap = new LeonardoHeap(); + assertEquals(0, heap.getHeapsize()); + + heap.addElement("z"); + assertEquals(1, heap.getHeapsize()); + + heap.addElement("a"); + assertEquals(2, heap.getHeapsize()); + + heap.removeElement(); + assertEquals(1, heap.getHeapsize()); + + heap.removeElement(); + assertEquals(0, heap.getHeapsize()); + } +} From edbf08aaf5d5b7ed6c0c890d37e510a2da92c091 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Mon, 8 Jul 2024 14:35:08 +0530 Subject: [PATCH 22/32] UMTP_UNBOUND_METHOD_TEMPLATE_PARAMETER mvn spotbug fix --- .../datastructures/heaps/LeonardoHeapTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java index eda624af944d..c55f5e2ff62d 100644 --- a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java @@ -1,18 +1,19 @@ package com.thealgorithms.datastructures.heaps; import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.Test; public class LeonardoHeapTest { @Test - public > void testEmpty() { + public void testEmpty() { LeonardoHeap heap = new LeonardoHeap(); assertEquals(0, heap.getHeapsize()); } @Test - public > void testAddElement() { + public void testAddElement() { LeonardoHeap heap = new LeonardoHeap<>(); heap.addElement(5); heap.addElement(3); @@ -53,7 +54,7 @@ public void testHeapSize() { } @Test - public > void testAddElementStrings() { + public void testAddElementStrings() { LeonardoHeap heap = new LeonardoHeap(); heap.addElement("z"); heap.addElement("a"); From 01ba46024e378eaf342ddf542b57e1fab7cf6ac2 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Thu, 18 Jul 2024 13:58:15 +0530 Subject: [PATCH 23/32] Rename members and add tests --- .../datastructures/heaps/LeonardoHeap.java | 118 ++++++++---------- .../com/thealgorithms/sorts/SmoothSort.java | 7 +- .../heaps/LeonardoHeapTest.java | 104 +++++++++------ 3 files changed, 119 insertions(+), 110 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java index a4c1d6f62623..0a9f21126bed 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java @@ -10,102 +10,86 @@ */ public class LeonardoHeap> { - private int leonardoLevelTracker; - private int leonardoHeapSize; - private final List leonardoHeap; + private int levelTracker = 0; + private final List heap = new ArrayList(); public LeonardoHeap() { - this.leonardoHeap = new ArrayList(); - this.leonardoLevelTracker = 0; - this.leonardoHeapSize = 0; } - public int getHeapsize() { - return this.leonardoHeapSize; - } - - private void decreaseLeonardoLevelTracker() { + private void decreaseLevelTracker() { int lastTreeLevel = getRightMostTree(); - leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, lastTreeLevel); + levelTracker = SingleBitOperations.clearBit(levelTracker, lastTreeLevel); if (lastTreeLevel != 0 && lastTreeLevel != 1) { - leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, lastTreeLevel - 1); - leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, lastTreeLevel - 2); + levelTracker = SingleBitOperations.setBit(levelTracker, lastTreeLevel - 1); + levelTracker = SingleBitOperations.setBit(levelTracker, lastTreeLevel - 2); } } - private void increaseLeonardoLevelTracker() { - ArrayList consecutiveTreeIndices = findConsecutiveLeonardoTreeIndices(leonardoLevelTracker); + private void increaseLevelTracker() { + ArrayList consecutiveTreeIndices = findConsecutiveTreeIndices(levelTracker); if (consecutiveTreeIndices.get(0) != -1) { // if 0th or 1st index is -1 that implies there are no concequtive trees - leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices.get(0)); - leonardoLevelTracker = SingleBitOperations.clearBit(leonardoLevelTracker, consecutiveTreeIndices.get(1)); - leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, consecutiveTreeIndices.get(1) + 1); - } else if ((leonardoLevelTracker & 2) == 0) { - leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, 1); + levelTracker = SingleBitOperations.clearBit(levelTracker, consecutiveTreeIndices.get(0)); + levelTracker = SingleBitOperations.clearBit(levelTracker, consecutiveTreeIndices.get(1)); + levelTracker = SingleBitOperations.setBit(levelTracker, consecutiveTreeIndices.get(1) + 1); + } else if ((levelTracker & 2) == 0) { + levelTracker = SingleBitOperations.setBit(levelTracker, 1); } else { - leonardoLevelTracker = SingleBitOperations.setBit(leonardoLevelTracker, 0); + levelTracker = SingleBitOperations.setBit(levelTracker, 0); } } - private void decreaseHeapSize() { - this.leonardoHeapSize--; - } - - private void increaseHeapSize() { - this.leonardoHeapSize++; - } - - private void maxHeapifyLeonardoTree(int rootNodeIndex, int currentLeonardoLevel) { + private void maxHeapifyTree(int rootNodeIndex, int currentLevel) { // A leonardo tree of level n is just 1 node(the root) plus the leonardo tree of n-1 level(left child) plus leonardo tree of n-2 level(right child) // To maxheapify a leonardo tree we need to compare the current root and roots of it's left and right subtree - // We recursively hepify the left and right subtrees using the currentLeonardoLevel + // We recursively hepify the left and right subtrees using the currentLevel // BASE CASE - if (currentLeonardoLevel == 0 || currentLeonardoLevel == 1) { + if (currentLevel == 0 || currentLevel == 1) { return; // Trees with one node are in already max-heapified. } int currentRootNodeIndex = rootNodeIndex; int rightChildIndex = rootNodeIndex - 1; - int leftChildIndex = rootNodeIndex - LeonardoNumber.leonardoNumber(currentLeonardoLevel - 2) - 1; + int leftChildIndex = rootNodeIndex - LeonardoNumber.leonardoNumber(currentLevel - 2) - 1; int childIndexForSwap = -1; - if (leonardoHeap.get(rightChildIndex).compareTo(leonardoHeap.get(leftChildIndex)) >= 0) { + if (heap.get(rightChildIndex).compareTo(heap.get(leftChildIndex)) >= 0) { childIndexForSwap = rightChildIndex; } else { childIndexForSwap = leftChildIndex; } - if (leonardoHeap.get(childIndexForSwap).compareTo(leonardoHeap.get(currentRootNodeIndex)) > 0) { + if (heap.get(childIndexForSwap).compareTo(heap.get(currentRootNodeIndex)) > 0) { swap(currentRootNodeIndex, childIndexForSwap); if (childIndexForSwap == rightChildIndex) { - maxHeapifyLeonardoTree(rightChildIndex, currentLeonardoLevel - 2); + maxHeapifyTree(rightChildIndex, currentLevel - 2); } else { // swap happened with the left child - maxHeapifyLeonardoTree(leftChildIndex, currentLeonardoLevel - 1); + maxHeapifyTree(leftChildIndex, currentLevel - 1); } } } private void shiftRootAndRestoreHeap() { - if (getHeapsize() == 0) { + if (heap.size() == 0) { return; } - Integer[] currentLeonardoTreeLevels = findAllLeonardoTreeIndices(); + Integer[] currentTreeLevels = findAllTreeIndices(); int previousTreeSizeCumulative = 0; ArrayList rootNodeIndices = new ArrayList(); // The number of roots are going to be same the the number of levels - // iterate over the currentLeonardoTreeLevels and get roots + // iterate over the currentTreeLevels and get roots - for (int i = 0; i < currentLeonardoTreeLevels.length; i++) { - rootNodeIndices.add(previousTreeSizeCumulative + LeonardoNumber.leonardoNumber(currentLeonardoTreeLevels[i]) - 1); - previousTreeSizeCumulative = previousTreeSizeCumulative + LeonardoNumber.leonardoNumber(currentLeonardoTreeLevels[i]); + for (int i = 0; i < currentTreeLevels.length; i++) { + rootNodeIndices.add(previousTreeSizeCumulative + LeonardoNumber.leonardoNumber(currentTreeLevels[i]) - 1); + previousTreeSizeCumulative = previousTreeSizeCumulative + LeonardoNumber.leonardoNumber(currentTreeLevels[i]); } int rootNodeIndexForHeapify = rootNodeIndices.getLast(); - int leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[currentLeonardoTreeLevels.length - 1]; + int treeLevelforHeapify = currentTreeLevels[currentTreeLevels.length - 1]; boolean swaped = false; for (int i = 1; i < rootNodeIndices.size(); i++) { @@ -113,26 +97,26 @@ private void shiftRootAndRestoreHeap() { int currentRootNodeIndex = rootNodeIndices.get(i); int prevRootNodeIndex = rootNodeIndices.get(i - 1); int j = i; - while (leonardoHeap.get(prevRootNodeIndex).compareTo(leonardoHeap.get(currentRootNodeIndex)) > 0) { - int currentLeonardoLevel = currentLeonardoTreeLevels[j]; - if (currentLeonardoLevel > 1) { + while (heap.get(prevRootNodeIndex).compareTo(heap.get(currentRootNodeIndex)) > 0) { + int currentLevel = currentTreeLevels[j]; + if (currentLevel > 1) { // compare child and swap int indexOfRightChild = rootNodeIndices.get(j) - 1; // right child is of level n-2 - int indexOfLeftChild = rootNodeIndices.get(j) - 1 - LeonardoNumber.leonardoNumber(currentLeonardoLevel - 2); - if (leonardoHeap.get(prevRootNodeIndex).compareTo(leonardoHeap.get(indexOfRightChild)) > 0 && leonardoHeap.get(prevRootNodeIndex).compareTo(leonardoHeap.get(indexOfLeftChild)) > 0) { + int indexOfLeftChild = rootNodeIndices.get(j) - 1 - LeonardoNumber.leonardoNumber(currentLevel - 2); + if (heap.get(prevRootNodeIndex).compareTo(heap.get(indexOfRightChild)) > 0 && heap.get(prevRootNodeIndex).compareTo(heap.get(indexOfLeftChild)) > 0) { swap(prevRootNodeIndex, currentRootNodeIndex); rootNodeIndexForHeapify = prevRootNodeIndex; - leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; + treeLevelforHeapify = currentTreeLevels[j - 1]; swaped = true; } else { - maxHeapifyLeonardoTree(currentRootNodeIndex, currentLeonardoLevel); + maxHeapifyTree(currentRootNodeIndex, currentLevel); swaped = false; } } else { swap(prevRootNodeIndex, currentRootNodeIndex); rootNodeIndexForHeapify = prevRootNodeIndex; - leonardoTreeLevelforHeapify = currentLeonardoTreeLevels[j - 1]; + treeLevelforHeapify = currentTreeLevels[j - 1]; swaped = true; } j = j - 1; @@ -146,17 +130,17 @@ private void shiftRootAndRestoreHeap() { } if (swaped) { - maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify); + maxHeapifyTree(rootNodeIndexForHeapify, treeLevelforHeapify); swaped = false; } } - maxHeapifyLeonardoTree(rootNodeIndexForHeapify, leonardoTreeLevelforHeapify); // In case of insert and no swap. + maxHeapifyTree(rootNodeIndexForHeapify, treeLevelforHeapify); // In case of insert and no swap. } private int getRightMostTree() { // Isolate the rightmost set bit - int isolatedBit = leonardoLevelTracker & -leonardoLevelTracker; + int isolatedBit = levelTracker & -levelTracker; int position = 0; while (isolatedBit > 1) { @@ -167,7 +151,7 @@ private int getRightMostTree() { return position; } - private static ArrayList findConsecutiveLeonardoTreeIndices(int num) { + private static ArrayList findConsecutiveTreeIndices(int num) { int prevOneIndex = -1; int currentLevel; @@ -192,15 +176,15 @@ private static ArrayList findConsecutiveLeonardoTreeIndices(int num) { } private void swap(int i, int j) { - T temp = leonardoHeap.get(i); - leonardoHeap.set(i, leonardoHeap.get(j)); - leonardoHeap.set(j, temp); + T temp = heap.get(i); + heap.set(i, heap.get(j)); + heap.set(j, temp); } - private Integer[] findAllLeonardoTreeIndices() { + private Integer[] findAllTreeIndices() { List setBitIndexes = new ArrayList<>(); for (int i = Integer.SIZE - 1; i >= 0; i--) { - if ((leonardoLevelTracker & (1 << i)) != 0) { + if ((levelTracker & (1 << i)) != 0) { setBitIndexes.add(i); } } @@ -208,16 +192,14 @@ private Integer[] findAllLeonardoTreeIndices() { } public void addElement(T element) { - increaseLeonardoLevelTracker(); - leonardoHeap.add(element); - increaseHeapSize(); + increaseLevelTracker(); + heap.add(element); shiftRootAndRestoreHeap(); } public T removeElement() { - decreaseLeonardoLevelTracker(); - decreaseHeapSize(); - T element = leonardoHeap.removeLast(); + decreaseLevelTracker(); + T element = heap.removeLast(); shiftRootAndRestoreHeap(); return element; diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 77c737a05a0e..6339ab795ce9 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -13,13 +13,12 @@ public SmoothSort() { private static > void smoothSort(T[] array) { LeonardoHeap leonardoHeap = new LeonardoHeap(); - for (int i = 0; i < array.length; i++) { - leonardoHeap.addElement(array[i]); + for (final var element: array) { + leonardoHeap.addElement(element); } for (int i = 0; i < array.length; i++) { - final T maxElement = leonardoHeap.removeElement(); - array[array.length - i - 1] = maxElement; + array[array.length - i - 1] = leonardoHeap.removeElement();; } } diff --git a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java index c55f5e2ff62d..93609b27d772 100644 --- a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java @@ -2,16 +2,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + import org.junit.jupiter.api.Test; public class LeonardoHeapTest { - @Test - public void testEmpty() { - LeonardoHeap heap = new LeonardoHeap(); - assertEquals(0, heap.getHeapsize()); - } - @Test public void testAddElement() { LeonardoHeap heap = new LeonardoHeap<>(); @@ -19,7 +17,6 @@ public void testAddElement() { heap.addElement(3); heap.addElement(8); - assertEquals(3, heap.getHeapsize()); assertEquals(8, heap.removeElement()); // Max element should be 8 } @@ -35,24 +32,6 @@ public void testRemoveElement() { assertEquals(5, heap.removeElement()); } - @Test - public void testHeapSize() { - LeonardoHeap heap = new LeonardoHeap<>(); - assertEquals(0, heap.getHeapsize()); - - heap.addElement(1); - assertEquals(1, heap.getHeapsize()); - - heap.addElement(2); - assertEquals(2, heap.getHeapsize()); - - heap.removeElement(); - assertEquals(1, heap.getHeapsize()); - - heap.removeElement(); - assertEquals(0, heap.getHeapsize()); - } - @Test public void testAddElementStrings() { LeonardoHeap heap = new LeonardoHeap(); @@ -62,8 +41,7 @@ public void testAddElementStrings() { heap.addElement("b"); heap.addElement("y"); - assertEquals(5, heap.getHeapsize()); - assertEquals("z", heap.removeElement()); // Max element should be 8 + assertEquals("z", heap.removeElement()); // Max element should be z } @Test @@ -79,20 +57,70 @@ public void testRemoveElementString() { } @Test - public void testHeapSizeString() { - LeonardoHeap heap = new LeonardoHeap(); - assertEquals(0, heap.getHeapsize()); + public void testAlwaysCurrentMaxElementIsRemoved() { + LeonardoHeap heap = new LeonardoHeap<>(); + heap.addElement(5); + heap.addElement(8); + heap.addElement(7); + heap.addElement(3); + + heap.addElement(4); + heap.addElement(4); + heap.addElement(4); + heap.addElement(6); - heap.addElement("z"); - assertEquals(1, heap.getHeapsize()); + heap.addElement(8); + heap.addElement(8); - heap.addElement("a"); - assertEquals(2, heap.getHeapsize()); + assertEquals(8, heap.removeElement()); + assertEquals(8, heap.removeElement()); + assertEquals(8, heap.removeElement()); + assertEquals(7, heap.removeElement()); + + assertEquals(6, heap.removeElement()); + assertEquals(5, heap.removeElement()); + assertEquals(4, heap.removeElement()); + assertEquals(4, heap.removeElement()); + + assertEquals(4, heap.removeElement()); + assertEquals(3, heap.removeElement()); + } + + @Test + public void testForCompareChildAndSwap() { + LeonardoHeap heap = new LeonardoHeap<>(); - heap.removeElement(); - assertEquals(1, heap.getHeapsize()); + heap.addElement(5); + heap.addElement(33); + heap.addElement(40); + heap.addElement(28); + + heap.addElement(95); + heap.addElement(29); + heap.addElement(88); + heap.addElement(94); + + heap.addElement(12); + heap.addElement(84); + heap.addElement(15); + heap.addElement(33); - heap.removeElement(); - assertEquals(0, heap.getHeapsize()); + heap.addElement(2); + heap.addElement(52); + heap.addElement(37); + heap.addElement(62); + + heap.addElement(48); + heap.addElement(13); + heap.addElement(61); + heap.addElement(59); + + // Assert the top 4 elemets are extracted correctly + assertEquals(95, heap.removeElement()); + assertEquals(94, heap.removeElement()); + assertEquals(88, heap.removeElement()); + assertEquals(84, heap.removeElement()); } + + } From fa0797f0b1656a5152e0f68e51e4f753ad838d84 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Thu, 18 Jul 2024 14:10:56 +0530 Subject: [PATCH 24/32] pmd errors fix --- src/main/java/com/thealgorithms/sorts/SmoothSort.java | 4 ++-- .../datastructures/heaps/LeonardoHeapTest.java | 10 ++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/SmoothSort.java b/src/main/java/com/thealgorithms/sorts/SmoothSort.java index 6339ab795ce9..244eb11ce23c 100644 --- a/src/main/java/com/thealgorithms/sorts/SmoothSort.java +++ b/src/main/java/com/thealgorithms/sorts/SmoothSort.java @@ -13,12 +13,12 @@ public SmoothSort() { private static > void smoothSort(T[] array) { LeonardoHeap leonardoHeap = new LeonardoHeap(); - for (final var element: array) { + for (final var element : array) { leonardoHeap.addElement(element); } for (int i = 0; i < array.length; i++) { - array[array.length - i - 1] = leonardoHeap.removeElement();; + array[array.length - i - 1] = leonardoHeap.removeElement(); } } diff --git a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java index 93609b27d772..df536a51ae05 100644 --- a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java @@ -2,10 +2,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - import org.junit.jupiter.api.Test; public class LeonardoHeapTest { @@ -63,7 +59,7 @@ public void testAlwaysCurrentMaxElementIsRemoved() { heap.addElement(8); heap.addElement(7); heap.addElement(3); - + heap.addElement(4); heap.addElement(4); heap.addElement(4); @@ -94,7 +90,7 @@ public void testForCompareChildAndSwap() { heap.addElement(33); heap.addElement(40); heap.addElement(28); - + heap.addElement(95); heap.addElement(29); heap.addElement(88); @@ -121,6 +117,4 @@ public void testForCompareChildAndSwap() { assertEquals(88, heap.removeElement()); assertEquals(84, heap.removeElement()); } - - } From ba730d0183ec09560d697e87341f4dbc36950b97 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Thu, 18 Jul 2024 14:16:58 +0530 Subject: [PATCH 25/32] spotbug fix --- .../com/thealgorithms/datastructures/heaps/LeonardoHeap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java index 0a9f21126bed..b7c38c2daf28 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java @@ -72,7 +72,7 @@ private void maxHeapifyTree(int rootNodeIndex, int currentLevel) { private void shiftRootAndRestoreHeap() { - if (heap.size() == 0) { + if (heap.isEmpty()) { return; } From a8a58353280c54d93e82c1836eae427a94bb9d54 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Fri, 19 Jul 2024 14:17:56 +0530 Subject: [PATCH 26/32] Added LeonardoHeapHelper.java --- .../datastructures/heaps/LeonardoHeap.java | 38 +--------- .../heaps/LeonardoHeapHelper.java | 45 +++++++++++ .../heaps/LeonardoHeapHelperTest.java | 74 +++++++++++++++++++ .../heaps/LeonardoHeapTest.java | 28 +------ 4 files changed, 125 insertions(+), 60 deletions(-) create mode 100644 src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelper.java create mode 100644 src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelperTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java index b7c38c2daf28..2fed4e0e4eaa 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java @@ -26,7 +26,7 @@ private void decreaseLevelTracker() { } private void increaseLevelTracker() { - ArrayList consecutiveTreeIndices = findConsecutiveTreeIndices(levelTracker); + ArrayList consecutiveTreeIndices = LeonardoHeapHelper.findConsecutiveTreeIndices(levelTracker); if (consecutiveTreeIndices.get(0) != -1) { // if 0th or 1st index is -1 that implies there are no concequtive trees levelTracker = SingleBitOperations.clearBit(levelTracker, consecutiveTreeIndices.get(0)); @@ -76,7 +76,7 @@ private void shiftRootAndRestoreHeap() { return; } - Integer[] currentTreeLevels = findAllTreeIndices(); + Integer[] currentTreeLevels = LeonardoHeapHelper.findAllTreeIndices(levelTracker); int previousTreeSizeCumulative = 0; ArrayList rootNodeIndices = new ArrayList(); @@ -151,46 +151,12 @@ private int getRightMostTree() { return position; } - private static ArrayList findConsecutiveTreeIndices(int num) { - int prevOneIndex = -1; - int currentLevel; - - ArrayList answer = new ArrayList(); - answer.add(-1); - answer.add(-1); - - for (int i = 0; num > 0; i++) { - currentLevel = num & 1; - if (currentLevel == 1) { - if (prevOneIndex != -1) { - answer.set(0, prevOneIndex); - answer.set(1, i); - } - prevOneIndex = i; - } else { - prevOneIndex = -1; - } - num >>>= 1; - } - return answer; - } - private void swap(int i, int j) { T temp = heap.get(i); heap.set(i, heap.get(j)); heap.set(j, temp); } - private Integer[] findAllTreeIndices() { - List setBitIndexes = new ArrayList<>(); - for (int i = Integer.SIZE - 1; i >= 0; i--) { - if ((levelTracker & (1 << i)) != 0) { - setBitIndexes.add(i); - } - } - return setBitIndexes.toArray(new Integer[0]); - } - public void addElement(T element) { increaseLevelTracker(); heap.add(element); diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelper.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelper.java new file mode 100644 index 000000000000..0f5e104696ca --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelper.java @@ -0,0 +1,45 @@ +package com.thealgorithms.datastructures.heaps; + +import java.util.ArrayList; +import java.util.List; + +// TODO: CHeck file name. Check if the file needs to be here or in bitwose operations. +public final class LeonardoHeapHelper { + + private LeonardoHeapHelper() { + } + + public static ArrayList findConsecutiveTreeIndices(int num) { + int prevOneIndex = -1; + int currentLevel = 0; + + ArrayList answer = new ArrayList(); + answer.add(-1); + answer.add(-1); + + for (int i = 0; num > 0; i++) { + currentLevel = num & 1; + if (currentLevel == 1) { + if (prevOneIndex != -1) { + answer.set(0, prevOneIndex); + answer.set(1, i); + } + prevOneIndex = i; + } else { + prevOneIndex = -1; + } + num >>>= 1; + } + return answer; + } + + public static Integer[] findAllTreeIndices(int num) { + List setBitIndexes = new ArrayList<>(); + for (int i = Integer.SIZE - 1; i >= 0; i--) { + if ((num & (1 << i)) != 0) { + setBitIndexes.add(i); + } + } + return setBitIndexes.toArray(new Integer[0]); + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelperTest.java b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelperTest.java new file mode 100644 index 000000000000..7c945ee149c5 --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelperTest.java @@ -0,0 +1,74 @@ +package com.thealgorithms.datastructures.heaps; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +// TODO: CHeck file name. Check if the file needs to be here or in bitwose operations. +public class LeonardoHeapHelperTest { + + @Test + public void testConsecutiveTreeIndicesForZero() { + ArrayList arrayList = LeonardoHeapHelper.findConsecutiveTreeIndices(0); + ArrayList expectedList = new ArrayList<>(Arrays.asList(-1, -1)); + + assertEquals(expectedList, arrayList); + } + + @Test + public void testConsecutiveTreeIndicesForEleven() { + ArrayList arrayList = LeonardoHeapHelper.findConsecutiveTreeIndices(11); + ArrayList expectedList = new ArrayList<>(Arrays.asList(0, 1)); + + assertEquals(expectedList, arrayList); + } + + @Test + public void testConsecutiveTreeIndicesForSixteen() { + ArrayList arrayList = LeonardoHeapHelper.findConsecutiveTreeIndices(16); + ArrayList expectedList = new ArrayList<>(Arrays.asList(-1, -1)); + + assertEquals(expectedList, arrayList); + } + + @Test + public void testConsecutiveTreeIndicesForTwentyFour() { + ArrayList arrayList = LeonardoHeapHelper.findConsecutiveTreeIndices(24); + ArrayList expectedList = new ArrayList<>(Arrays.asList(3, 4)); + + assertEquals(expectedList, arrayList); + } + + @Test + public void testfindAllTreeIndicesForZero() { + Integer[] array = LeonardoHeapHelper.findAllTreeIndices(0); + assertEquals(0, array.length); + } + + @Test + public void testfindAllTreeIndicesForEleven() { + Integer[] array = LeonardoHeapHelper.findAllTreeIndices(11); + Integer[] expectedArray = new Integer[] {3, 1, 0}; + + assertTrue(Arrays.equals(expectedArray, array)); + } + + @Test + public void testfindAllTreeIndicesForSixteen() { + Integer[] array = LeonardoHeapHelper.findAllTreeIndices(16); + Integer[] expectedArray = new Integer[] {4}; + + assertTrue(Arrays.equals(expectedArray, array)); + } + + @Test + public void testfindAllTreeIndicesForTwentyFour() { + Integer[] array = LeonardoHeapHelper.findAllTreeIndices(24); + Integer[] expectedArray = new Integer[] {4, 3}; + + assertTrue(Arrays.equals(expectedArray, array)); + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java index df536a51ae05..5e2f6812200f 100644 --- a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java @@ -85,31 +85,11 @@ public void testAlwaysCurrentMaxElementIsRemoved() { @Test public void testForCompareChildAndSwap() { LeonardoHeap heap = new LeonardoHeap<>(); + Integer[] elements = {5, 33, 40, 28, 95, 29, 88, 94, 12, 84, 15, 33, 2, 52, 37, 62, 48, 13, 61, 59}; - heap.addElement(5); - heap.addElement(33); - heap.addElement(40); - heap.addElement(28); - - heap.addElement(95); - heap.addElement(29); - heap.addElement(88); - heap.addElement(94); - - heap.addElement(12); - heap.addElement(84); - heap.addElement(15); - heap.addElement(33); - - heap.addElement(2); - heap.addElement(52); - heap.addElement(37); - heap.addElement(62); - - heap.addElement(48); - heap.addElement(13); - heap.addElement(61); - heap.addElement(59); + for (Integer element : elements) { + heap.addElement(element); + } // Assert the top 4 elemets are extracted correctly assertEquals(95, heap.removeElement()); From 37c794b47826e3a12d77afbc3f4923685fd950df Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Mon, 22 Jul 2024 19:02:49 +0530 Subject: [PATCH 27/32] Removed Helper Class, formatted to make items final. --- .../datastructures/heaps/LeonardoHeap.java | 86 ++++++++++++------- .../heaps/LeonardoHeapHelper.java | 45 ---------- .../heaps/LeonardoHeapHelperTest.java | 74 ---------------- 3 files changed, 57 insertions(+), 148 deletions(-) delete mode 100644 src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelper.java delete mode 100644 src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelperTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java index 2fed4e0e4eaa..0530cf8f20e3 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java @@ -1,10 +1,12 @@ package com.thealgorithms.datastructures.heaps; -import com.thealgorithms.bitmanipulation.SingleBitOperations; -import com.thealgorithms.maths.LeonardoNumber; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import com.thealgorithms.bitmanipulation.SingleBitOperations; +import com.thealgorithms.maths.LeonardoNumber; + /** * Wikipedia: https://en.wikipedia.org/wiki/Smoothsort */ @@ -17,7 +19,7 @@ public LeonardoHeap() { } private void decreaseLevelTracker() { - int lastTreeLevel = getRightMostTree(); + final int lastTreeLevel = getRightMostTree(); levelTracker = SingleBitOperations.clearBit(levelTracker, lastTreeLevel); if (lastTreeLevel != 0 && lastTreeLevel != 1) { levelTracker = SingleBitOperations.setBit(levelTracker, lastTreeLevel - 1); @@ -26,7 +28,7 @@ private void decreaseLevelTracker() { } private void increaseLevelTracker() { - ArrayList consecutiveTreeIndices = LeonardoHeapHelper.findConsecutiveTreeIndices(levelTracker); + final ArrayList consecutiveTreeIndices = findConsecutiveTreeIndices(levelTracker); if (consecutiveTreeIndices.get(0) != -1) { // if 0th or 1st index is -1 that implies there are no concequtive trees levelTracker = SingleBitOperations.clearBit(levelTracker, consecutiveTreeIndices.get(0)); @@ -49,16 +51,10 @@ private void maxHeapifyTree(int rootNodeIndex, int currentLevel) { return; // Trees with one node are in already max-heapified. } - int currentRootNodeIndex = rootNodeIndex; - int rightChildIndex = rootNodeIndex - 1; - int leftChildIndex = rootNodeIndex - LeonardoNumber.leonardoNumber(currentLevel - 2) - 1; - int childIndexForSwap = -1; - - if (heap.get(rightChildIndex).compareTo(heap.get(leftChildIndex)) >= 0) { - childIndexForSwap = rightChildIndex; - } else { - childIndexForSwap = leftChildIndex; - } + final int currentRootNodeIndex = rootNodeIndex; + final int rightChildIndex = rootNodeIndex - 1; + final int leftChildIndex = rootNodeIndex - LeonardoNumber.leonardoNumber(currentLevel - 2) - 1; + final int childIndexForSwap = (heap.get(rightChildIndex).compareTo(heap.get(leftChildIndex)) >= 0) ? rightChildIndex : leftChildIndex; if (heap.get(childIndexForSwap).compareTo(heap.get(currentRootNodeIndex)) > 0) { swap(currentRootNodeIndex, childIndexForSwap); @@ -76,7 +72,7 @@ private void shiftRootAndRestoreHeap() { return; } - Integer[] currentTreeLevels = LeonardoHeapHelper.findAllTreeIndices(levelTracker); + final Integer[] currentTreeLevels = findAllTreeIndices(levelTracker); int previousTreeSizeCumulative = 0; ArrayList rootNodeIndices = new ArrayList(); @@ -90,34 +86,35 @@ private void shiftRootAndRestoreHeap() { int rootNodeIndexForHeapify = rootNodeIndices.getLast(); int treeLevelforHeapify = currentTreeLevels[currentTreeLevels.length - 1]; - boolean swaped = false; for (int i = 1; i < rootNodeIndices.size(); i++) { int currentRootNodeIndex = rootNodeIndices.get(i); int prevRootNodeIndex = rootNodeIndices.get(i - 1); int j = i; + boolean swapped = false; + while (heap.get(prevRootNodeIndex).compareTo(heap.get(currentRootNodeIndex)) > 0) { - int currentLevel = currentTreeLevels[j]; + final int currentLevel = currentTreeLevels[j]; if (currentLevel > 1) { // compare child and swap - int indexOfRightChild = rootNodeIndices.get(j) - 1; // right child is of level n-2 - int indexOfLeftChild = rootNodeIndices.get(j) - 1 - LeonardoNumber.leonardoNumber(currentLevel - 2); - if (heap.get(prevRootNodeIndex).compareTo(heap.get(indexOfRightChild)) > 0 && heap.get(prevRootNodeIndex).compareTo(heap.get(indexOfLeftChild)) > 0) { + final int rightChildIndex = rootNodeIndices.get(j) - 1; // right child is of level n-2 + final int leftChildIndex = rootNodeIndices.get(j) - 1 - LeonardoNumber.leonardoNumber(currentLevel - 2); + if (heap.get(prevRootNodeIndex).compareTo(heap.get(rightChildIndex)) > 0 && heap.get(prevRootNodeIndex).compareTo(heap.get(leftChildIndex)) > 0) { swap(prevRootNodeIndex, currentRootNodeIndex); rootNodeIndexForHeapify = prevRootNodeIndex; treeLevelforHeapify = currentTreeLevels[j - 1]; - swaped = true; + swapped = true; } else { maxHeapifyTree(currentRootNodeIndex, currentLevel); - swaped = false; + swapped = false; } } else { swap(prevRootNodeIndex, currentRootNodeIndex); rootNodeIndexForHeapify = prevRootNodeIndex; treeLevelforHeapify = currentTreeLevels[j - 1]; - swaped = true; + swapped = true; } j = j - 1; if (j > 0) { @@ -129,9 +126,8 @@ private void shiftRootAndRestoreHeap() { } } - if (swaped) { + if (swapped) { maxHeapifyTree(rootNodeIndexForHeapify, treeLevelforHeapify); - swaped = false; } } @@ -152,9 +148,7 @@ private int getRightMostTree() { } private void swap(int i, int j) { - T temp = heap.get(i); - heap.set(i, heap.get(j)); - heap.set(j, temp); + Collections.swap(heap, i, j); } public void addElement(T element) { @@ -165,9 +159,43 @@ public void addElement(T element) { public T removeElement() { decreaseLevelTracker(); - T element = heap.removeLast(); + final T element = heap.removeLast(); shiftRootAndRestoreHeap(); return element; } + + private static ArrayList findConsecutiveTreeIndices(int num) { + int prevOneIndex = -1; + int currentLevel = 0; + + ArrayList answer = new ArrayList(); + answer.add(-1); + answer.add(-1); + + for (int i = 0; num > 0; i++) { + currentLevel = num & 1; + if (currentLevel == 1) { + if (prevOneIndex != -1) { + answer.set(0, prevOneIndex); + answer.set(1, i); + } + prevOneIndex = i; + } else { + prevOneIndex = -1; + } + num >>>= 1; + } + return answer; + } + + private static Integer[] findAllTreeIndices(int num) { + List setBitIndexes = new ArrayList<>(); + for (int i = Integer.SIZE - 1; i >= 0; i--) { + if ((num & (1 << i)) != 0) { + setBitIndexes.add(i); + } + } + return setBitIndexes.toArray(new Integer[0]); + } } diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelper.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelper.java deleted file mode 100644 index 0f5e104696ca..000000000000 --- a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelper.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.thealgorithms.datastructures.heaps; - -import java.util.ArrayList; -import java.util.List; - -// TODO: CHeck file name. Check if the file needs to be here or in bitwose operations. -public final class LeonardoHeapHelper { - - private LeonardoHeapHelper() { - } - - public static ArrayList findConsecutiveTreeIndices(int num) { - int prevOneIndex = -1; - int currentLevel = 0; - - ArrayList answer = new ArrayList(); - answer.add(-1); - answer.add(-1); - - for (int i = 0; num > 0; i++) { - currentLevel = num & 1; - if (currentLevel == 1) { - if (prevOneIndex != -1) { - answer.set(0, prevOneIndex); - answer.set(1, i); - } - prevOneIndex = i; - } else { - prevOneIndex = -1; - } - num >>>= 1; - } - return answer; - } - - public static Integer[] findAllTreeIndices(int num) { - List setBitIndexes = new ArrayList<>(); - for (int i = Integer.SIZE - 1; i >= 0; i--) { - if ((num & (1 << i)) != 0) { - setBitIndexes.add(i); - } - } - return setBitIndexes.toArray(new Integer[0]); - } -} diff --git a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelperTest.java b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelperTest.java deleted file mode 100644 index 7c945ee149c5..000000000000 --- a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapHelperTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.thealgorithms.datastructures.heaps; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.Arrays; -import org.junit.jupiter.api.Test; - -// TODO: CHeck file name. Check if the file needs to be here or in bitwose operations. -public class LeonardoHeapHelperTest { - - @Test - public void testConsecutiveTreeIndicesForZero() { - ArrayList arrayList = LeonardoHeapHelper.findConsecutiveTreeIndices(0); - ArrayList expectedList = new ArrayList<>(Arrays.asList(-1, -1)); - - assertEquals(expectedList, arrayList); - } - - @Test - public void testConsecutiveTreeIndicesForEleven() { - ArrayList arrayList = LeonardoHeapHelper.findConsecutiveTreeIndices(11); - ArrayList expectedList = new ArrayList<>(Arrays.asList(0, 1)); - - assertEquals(expectedList, arrayList); - } - - @Test - public void testConsecutiveTreeIndicesForSixteen() { - ArrayList arrayList = LeonardoHeapHelper.findConsecutiveTreeIndices(16); - ArrayList expectedList = new ArrayList<>(Arrays.asList(-1, -1)); - - assertEquals(expectedList, arrayList); - } - - @Test - public void testConsecutiveTreeIndicesForTwentyFour() { - ArrayList arrayList = LeonardoHeapHelper.findConsecutiveTreeIndices(24); - ArrayList expectedList = new ArrayList<>(Arrays.asList(3, 4)); - - assertEquals(expectedList, arrayList); - } - - @Test - public void testfindAllTreeIndicesForZero() { - Integer[] array = LeonardoHeapHelper.findAllTreeIndices(0); - assertEquals(0, array.length); - } - - @Test - public void testfindAllTreeIndicesForEleven() { - Integer[] array = LeonardoHeapHelper.findAllTreeIndices(11); - Integer[] expectedArray = new Integer[] {3, 1, 0}; - - assertTrue(Arrays.equals(expectedArray, array)); - } - - @Test - public void testfindAllTreeIndicesForSixteen() { - Integer[] array = LeonardoHeapHelper.findAllTreeIndices(16); - Integer[] expectedArray = new Integer[] {4}; - - assertTrue(Arrays.equals(expectedArray, array)); - } - - @Test - public void testfindAllTreeIndicesForTwentyFour() { - Integer[] array = LeonardoHeapHelper.findAllTreeIndices(24); - Integer[] expectedArray = new Integer[] {4, 3}; - - assertTrue(Arrays.equals(expectedArray, array)); - } -} From c0b8737f9aa89ef8dc71a031be845916c50076cc Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Mon, 22 Jul 2024 19:04:36 +0530 Subject: [PATCH 28/32] Rework on formatting. --- .../com/thealgorithms/datastructures/heaps/LeonardoHeap.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java index 0530cf8f20e3..0c89273ddbad 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java @@ -1,12 +1,11 @@ package com.thealgorithms.datastructures.heaps; +import com.thealgorithms.bitmanipulation.SingleBitOperations; +import com.thealgorithms.maths.LeonardoNumber; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import com.thealgorithms.bitmanipulation.SingleBitOperations; -import com.thealgorithms.maths.LeonardoNumber; - /** * Wikipedia: https://en.wikipedia.org/wiki/Smoothsort */ From ad4c5401cf3c7b636f8fc70626394f14fba822c8 Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Wed, 24 Jul 2024 10:39:51 +0530 Subject: [PATCH 29/32] Reworking LeonardoHeap: shiftRootAndRestoreHeap --- .../datastructures/heaps/LeonardoHeap.java | 85 ++++++++++--------- .../heaps/LeonardoHeapTest.java | 4 +- 2 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java index 0c89273ddbad..5a5d521c7f62 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java @@ -12,7 +12,7 @@ public class LeonardoHeap> { private int levelTracker = 0; - private final List heap = new ArrayList(); + private final List heap = new ArrayList<>(); public LeonardoHeap() { } @@ -27,7 +27,7 @@ private void decreaseLevelTracker() { } private void increaseLevelTracker() { - final ArrayList consecutiveTreeIndices = findConsecutiveTreeIndices(levelTracker); + final List consecutiveTreeIndices = findConsecutiveTreeIndices(levelTracker); if (consecutiveTreeIndices.get(0) != -1) { // if 0th or 1st index is -1 that implies there are no concequtive trees levelTracker = SingleBitOperations.clearBit(levelTracker, consecutiveTreeIndices.get(0)); @@ -72,16 +72,7 @@ private void shiftRootAndRestoreHeap() { } final Integer[] currentTreeLevels = findAllTreeIndices(levelTracker); - int previousTreeSizeCumulative = 0; - ArrayList rootNodeIndices = new ArrayList(); - - // The number of roots are going to be same the the number of levels - // iterate over the currentTreeLevels and get roots - - for (int i = 0; i < currentTreeLevels.length; i++) { - rootNodeIndices.add(previousTreeSizeCumulative + LeonardoNumber.leonardoNumber(currentTreeLevels[i]) - 1); - previousTreeSizeCumulative = previousTreeSizeCumulative + LeonardoNumber.leonardoNumber(currentTreeLevels[i]); - } + ArrayList rootNodeIndices = getRootNodeIndices(currentTreeLevels); int rootNodeIndexForHeapify = rootNodeIndices.getLast(); int treeLevelforHeapify = currentTreeLevels[currentTreeLevels.length - 1]; @@ -91,42 +82,28 @@ private void shiftRootAndRestoreHeap() { int currentRootNodeIndex = rootNodeIndices.get(i); int prevRootNodeIndex = rootNodeIndices.get(i - 1); int j = i; - boolean swapped = false; - - while (heap.get(prevRootNodeIndex).compareTo(heap.get(currentRootNodeIndex)) > 0) { + while (compareRoots(currentRootNodeIndex, prevRootNodeIndex)) { final int currentLevel = currentTreeLevels[j]; - if (currentLevel > 1) { + boolean swapRequired = compareChildren(currentRootNodeIndex, prevRootNodeIndex, currentLevel); + if (swapRequired) { // compare child and swap - - final int rightChildIndex = rootNodeIndices.get(j) - 1; // right child is of level n-2 - final int leftChildIndex = rootNodeIndices.get(j) - 1 - LeonardoNumber.leonardoNumber(currentLevel - 2); - if (heap.get(prevRootNodeIndex).compareTo(heap.get(rightChildIndex)) > 0 && heap.get(prevRootNodeIndex).compareTo(heap.get(leftChildIndex)) > 0) { - swap(prevRootNodeIndex, currentRootNodeIndex); - rootNodeIndexForHeapify = prevRootNodeIndex; - treeLevelforHeapify = currentTreeLevels[j - 1]; - swapped = true; - } else { - maxHeapifyTree(currentRootNodeIndex, currentLevel); - swapped = false; - } - } else { swap(prevRootNodeIndex, currentRootNodeIndex); rootNodeIndexForHeapify = prevRootNodeIndex; treeLevelforHeapify = currentTreeLevels[j - 1]; - swapped = true; + } else { + maxHeapifyTree(currentRootNodeIndex, currentLevel); } j = j - 1; - if (j > 0) { - currentRootNodeIndex = rootNodeIndices.get(j); - prevRootNodeIndex = rootNodeIndices.get(j - 1); - } else { - // j = 0 reached the left most tree + + if (j == 0) { + // We arrived at the left most tree. Do a maxheapifyTree if a swap had occurred + if (swapRequired) { + maxHeapifyTree(rootNodeIndexForHeapify, treeLevelforHeapify); + } break; } - } - - if (swapped) { - maxHeapifyTree(rootNodeIndexForHeapify, treeLevelforHeapify); + currentRootNodeIndex = rootNodeIndices.get(j); + prevRootNodeIndex = rootNodeIndices.get(j - 1); } } @@ -164,11 +141,11 @@ public T removeElement() { return element; } - private static ArrayList findConsecutiveTreeIndices(int num) { + private static List findConsecutiveTreeIndices(int num) { int prevOneIndex = -1; int currentLevel = 0; - ArrayList answer = new ArrayList(); + List answer = new ArrayList<>(); answer.add(-1); answer.add(-1); @@ -197,4 +174,30 @@ private static Integer[] findAllTreeIndices(int num) { } return setBitIndexes.toArray(new Integer[0]); } + + private boolean compareChildren(int currentRootNodeIndex, int prevRootNodeIndex, int currentLevel) { + if (currentLevel <= 1) { + // if there are no children to compare (L1 or L0 tree) return true + // because we already know that element at prevRootNodeIndex is greater than element at currentRootNodeIndex + // so a swap will be needed + return true; + } + final int rightChildIndex = currentRootNodeIndex - 1; + final int leftChildIndex = currentRootNodeIndex - 1 - LeonardoNumber.leonardoNumber(currentLevel - 2); + return heap.get(prevRootNodeIndex).compareTo(heap.get(rightChildIndex)) > 0 && heap.get(prevRootNodeIndex).compareTo(heap.get(leftChildIndex)) > 0; + } + + private boolean compareRoots(int currentRootNodeIndex, int prevRootNodeIndex) { + return heap.get(prevRootNodeIndex).compareTo(heap.get(currentRootNodeIndex)) > 0; + } + + private ArrayList getRootNodeIndices(Integer[] currentTreeLevels) { + int previousTreeSizeCumulative = 0; + ArrayList rootNodeIndices = new ArrayList<>(); + for (int i = 0; i < currentTreeLevels.length; i++) { + rootNodeIndices.add(previousTreeSizeCumulative + LeonardoNumber.leonardoNumber(currentTreeLevels[i]) - 1); + previousTreeSizeCumulative = previousTreeSizeCumulative + LeonardoNumber.leonardoNumber(currentTreeLevels[i]); + } + return rootNodeIndices; + } } diff --git a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java index 5e2f6812200f..3e7e534f387a 100644 --- a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java @@ -30,7 +30,7 @@ public void testRemoveElement() { @Test public void testAddElementStrings() { - LeonardoHeap heap = new LeonardoHeap(); + LeonardoHeap heap = new LeonardoHeap<>(); heap.addElement("z"); heap.addElement("a"); heap.addElement("x"); @@ -42,7 +42,7 @@ public void testAddElementStrings() { @Test public void testRemoveElementString() { - LeonardoHeap heap = new LeonardoHeap(); + LeonardoHeap heap = new LeonardoHeap<>(); heap.addElement("z"); heap.addElement("a"); heap.addElement("x"); From 0edabcd0ee1e29672bc0849c45959e16f4daba3a Mon Sep 17 00:00:00 2001 From: JAPNITSINGH Date: Wed, 24 Jul 2024 10:45:23 +0530 Subject: [PATCH 30/32] Lint issues in LeonardoHeap --- .../com/thealgorithms/datastructures/heaps/LeonardoHeap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java index 5a5d521c7f62..9c3d1c895410 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java @@ -96,7 +96,7 @@ private void shiftRootAndRestoreHeap() { j = j - 1; if (j == 0) { - // We arrived at the left most tree. Do a maxheapifyTree if a swap had occurred + // We arrived at the left most tree. Do a maxheapifyTree if a swap had occurred if (swapRequired) { maxHeapifyTree(rootNodeIndexForHeapify, treeLevelforHeapify); } From 6b4c415c312a8a9f8699a7c8d8c1459f5baf325a Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Tue, 6 Aug 2024 08:37:03 +0200 Subject: [PATCH 31/32] style: use predecrement operator --- .../com/thealgorithms/datastructures/heaps/LeonardoHeap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java index 9c3d1c895410..7d43c2db209a 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeonardoHeap.java @@ -93,7 +93,7 @@ private void shiftRootAndRestoreHeap() { } else { maxHeapifyTree(currentRootNodeIndex, currentLevel); } - j = j - 1; + --j; if (j == 0) { // We arrived at the left most tree. Do a maxheapifyTree if a swap had occurred From 174de3f5d9af5676980528179f3dbbcdc86bdff1 Mon Sep 17 00:00:00 2001 From: vil02 <65706193+vil02@users.noreply.github.com> Date: Tue, 6 Aug 2024 08:51:39 +0200 Subject: [PATCH 32/32] tests: add more checks into tests --- .../heaps/LeonardoHeapTest.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java index 3e7e534f387a..922adfbfcb0a 100644 --- a/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/heaps/LeonardoHeapTest.java @@ -14,6 +14,8 @@ public void testAddElement() { heap.addElement(8); assertEquals(8, heap.removeElement()); // Max element should be 8 + assertEquals(5, heap.removeElement()); + assertEquals(3, heap.removeElement()); } @Test @@ -38,6 +40,10 @@ public void testAddElementStrings() { heap.addElement("y"); assertEquals("z", heap.removeElement()); // Max element should be z + assertEquals("y", heap.removeElement()); + assertEquals("x", heap.removeElement()); + assertEquals("b", heap.removeElement()); + assertEquals("a", heap.removeElement()); } @Test @@ -91,10 +97,25 @@ public void testForCompareChildAndSwap() { heap.addElement(element); } - // Assert the top 4 elemets are extracted correctly assertEquals(95, heap.removeElement()); assertEquals(94, heap.removeElement()); assertEquals(88, heap.removeElement()); assertEquals(84, heap.removeElement()); + assertEquals(62, heap.removeElement()); + assertEquals(61, heap.removeElement()); + assertEquals(59, heap.removeElement()); + assertEquals(52, heap.removeElement()); + assertEquals(48, heap.removeElement()); + assertEquals(40, heap.removeElement()); + assertEquals(37, heap.removeElement()); + assertEquals(33, heap.removeElement()); + assertEquals(33, heap.removeElement()); + assertEquals(29, heap.removeElement()); + assertEquals(28, heap.removeElement()); + assertEquals(15, heap.removeElement()); + assertEquals(13, heap.removeElement()); + assertEquals(12, heap.removeElement()); + assertEquals(5, heap.removeElement()); + assertEquals(2, heap.removeElement()); } }