Repository: TheAlgorithms/Java
Pull request #5252 (2024-06-24 15:28:07)

feat: add `WaveSort`
Implementation for WaveSort Algorithm and test for it.

<!--
Thank you for your contribution!
In order to reduce the number of notifications sent to the maintainers, please:
- create your PR as draft, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests,
- make sure that all of the CI checks pass,
- mark your PR as ready for review, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request#marking-a-pull-request-as-ready-for-review
-->

<!-- For completed items, change [ ] to [x] -->

- [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
- [x] This pull request is all my own work -- I have not plagiarized it.
- [x] All filenames are in PascalCase.
- [x] All functions and variable names follow Java naming conventions.
- [x] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.
- [x] All new code is formatted with `clang-format -i --style=file path/to/your/file.java`

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/TheAlgorithms/Java/pull/5252?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 39.86%. Comparing base [(`a710fe1`)](https://app.codecov.io/gh/TheAlgorithms/Java/commit/a710fe11c47bdfb80342f851c189d167035b7b1c?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms) to head [(`6c940a4`)](https://app.codecov.io/gh/TheAlgorithms/Java/commit/6c940a40042b12770c3f54c75056513cd788f991?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff              @@
##             master    #5252      +/-   ##
============================================
+ Coverage     39.82%   39.86%   +0.03%     
- Complexity     2437     2444       +7     
============================================
  Files           517      518       +1     
  Lines         15476    15484       +8     
  Branches       2958     2961       +3     
============================================
+ Hits           6164     6172       +8     
  Misses         9022     9022              
  Partials        290      290              
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/TheAlgorithms/Java/pull/5252?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).


Patch:
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 7c46336f..c4eb2a6d 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -528,6 +528,7 @@
             * [TopologicalSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TopologicalSort.java)
             * [TreeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TreeSort.java)
             * [WiggleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/WiggleSort.java)
+            * [WaveSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/WaveSort.java)
           * stacks
             * [BalancedBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java)
             * [DecimalToAnyUsingStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java)
@@ -885,6 +886,7 @@
             * [TopologicalSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java)
             * [TreeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TreeSortTest.java)
             * [WiggleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java)
+            * [WaveSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/WaveSortTest.java)
           * stacks
             * [StackPostfixNotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java)
           * strings
diff --git a/src/main/java/com/thealgorithms/sorts/WaveSort.java b/src/main/java/com/thealgorithms/sorts/WaveSort.java
new file mode 100644
index 00000000..31aad52c
--- /dev/null
+++ b/src/main/java/com/thealgorithms/sorts/WaveSort.java
@@ -0,0 +1,46 @@
+package com.thealgorithms.sorts;
+
+/**
+ * The WaveSort algorithm sorts an array so that every alternate element is greater than its adjacent elements.
+ * This implementation also provides a method to check if an array is wave sorted.
+ */
+public class WaveSort implements SortAlgorithm {
+    /**
+     * Sorts the given array such that every alternate element is greater than its adjacent elements.
+     *
+     * @param array The array to be sorted.
+     * @param <T> The type of elements in the array, which must be Comparable.
+     * @return The sorted array.
+     */
+    @Override
+    public <T extends Comparable<T>> T[] sort(T[] array) {
+        for (int i = 0; i < array.length; i += 2) {
+            if (i > 0 && SortUtils.less(array[i], array[i - 1])) {
+                SortUtils.swap(array, i, i - 1);
+            }
+            if (i < array.length - 1 && SortUtils.less(array[i], array[i + 1])) {
+                SortUtils.swap(array, i, i + 1);
+            }
+        }
+        return array;
+    }
+
+    /**
+     * Checks if the given array is wave sorted. An array is wave sorted if every alternate element is greater than its adjacent elements.
+     *
+     * @param array The array to check.
+     * @param <T> The type of elements in the array, which must be Comparable.
+     * @return true if the array is wave sorted, false otherwise.
+     */
+    public <T extends Comparable<T>> boolean isWaveSorted(T[] array) {
+        for (int i = 0; i < array.length; i += 2) {
+            if (i > 0 && SortUtils.less(array[i], array[i - 1])) {
+                return false;
+            }
+            if (i < array.length - 1 && SortUtils.less(array[i], array[i + 1])) {
+                return false;
+            }
+        }
+        return true;
+    }
+}


Test patch:
diff --git a/src/test/java/com/thealgorithms/sorts/WaveSortTest.java b/src/test/java/com/thealgorithms/sorts/WaveSortTest.java
new file mode 100644
index 00000000..3bc6fa63
--- /dev/null
+++ b/src/test/java/com/thealgorithms/sorts/WaveSortTest.java
@@ -0,0 +1,48 @@
+package com.thealgorithms.sorts;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Stream;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class WaveSortTest {
+    @ParameterizedTest
+    @MethodSource("arraysToWaveSort")
+    public void waveSortTest(Integer[] array) {
+        WaveSort waveSort = new WaveSort();
+        final var inputHistogram = getHistogram(array);
+        final var sortedArray = waveSort.sort(array);
+        assertTrue(waveSort.isWaveSorted(sortedArray));
+        final var sortedHistogram = getHistogram(sortedArray);
+        assertEquals(inputHistogram, sortedHistogram, "Element counts do not match");
+    }
+
+    private Map<Integer, Integer> getHistogram(Integer[] array) {
+        Map<Integer, Integer> histogram = new HashMap<>();
+        for (final var element : array) {
+            histogram.put(element, histogram.getOrDefault(element, 0) + 1);
+        }
+        return histogram;
+    }
+
+    private static Stream<Object[]> arraysToWaveSort() {
+        return Stream.of(new Object[] {new Integer[] {7, 7, 11, 3, 4, 5, 15}}, new Object[] {new Integer[] {1, 2, 3, 4, 5, 6, 7, 8}}, new Object[] {new Integer[] {8, 7, 6, 5, 4, 3, 2, 1}}, new Object[] {new Integer[] {3, 3, 3, 3}}, new Object[] {new Integer[] {-1, -3, -2, -4, -6, -5}},
+            new Object[] {new Integer[] {5, 3, 1, 2, 9, 7, 6, 8, 4, 0}}, new Object[] {new Integer[] {1}}, new Object[] {new Integer[] {2, 1}}, new Object[] {new Integer[] {1, 2}}, new Object[] {new Integer[] {}}, new Object[] {new Integer[] {0, 5, -3, 2, -1, 4, -2, 1, 3}});
+    }
+
+    @ParameterizedTest
+    @MethodSource("waveSortedArrays")
+    public <T extends Comparable<T>> void testIsWaveSorted(T[] array, boolean expected) {
+        final WaveSort waveSort = new WaveSort();
+        assertEquals(expected, waveSort.isWaveSorted(array));
+    }
+    public static Stream<Object[]> waveSortedArrays() {
+        return Stream.of(new Object[] {new Integer[] {3, 1, 4, 2, 5}, Boolean.TRUE}, new Object[] {new Integer[] {3, 1, 4, 2}, Boolean.TRUE}, new Object[] {new Integer[] {1, 3, 2, 4, 5}, Boolean.FALSE}, new Object[] {new Integer[] {4, 3, 5, 2, 3, 1, 2}, Boolean.TRUE},
+            new Object[] {new Integer[] {10, 90, 49, 2, 1, 5, 23}, Boolean.FALSE}, new Object[] {new Integer[] {}, Boolean.TRUE}, new Object[] {new Integer[] {1}, Boolean.TRUE}, new Object[] {new Integer[] {2, 1}, Boolean.TRUE}, new Object[] {new Integer[] {4, 3, 2, 5}, Boolean.FALSE},
+            new Object[] {new Double[] {4.0, 3.0, 5.1, 2.1, 3.3, 1.1, 2.2}, Boolean.TRUE}, new Object[] {new Double[] {10.1, 2.0, 2.0}, Boolean.TRUE}, new Object[] {new String[] {"a", "b", "c", "d"}, Boolean.FALSE}, new Object[] {new String[] {"b", "a", "b", "a", "b"}, Boolean.TRUE});
+    }
+}