Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions src/main/java/com/thealgorithms/maths/Median.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,35 @@
import java.util.Arrays;

/**
* Wikipedia: https://en.wikipedia.org/wiki/Median
* Utility class for calculating the median of an array of integers.
* The median is the middle value in a sorted list of numbers. If the list has
* an even number
* of elements, the median is the average of the two middle values.
*
* <p>
* Time Complexity: O(n log n) due to sorting
* <p>
* Space Complexity: O(1) if sorting is done in-place
*
* @see <a href="https://en.wikipedia.org/wiki/Median">Median (Wikipedia)</a>
* @see <a href=
* "https://www.khanacademy.org/math/statistics-probability/summarizing-quantitative-data/mean-median-basics/a/mean-median-and-mode-review">Mean,
* Median, and Mode Review</a>
*/
public final class Median {
private Median() {
}

/**
* Calculate average median
* @param values sorted numbers to find median of
* @return median of given {@code values}
* @throws IllegalArgumentException If the input array is empty or null.
* Calculates the median of an array of integers.
* The array is sorted internally, so the original order is not preserved.
* For arrays with an odd number of elements, returns the middle element.
* For arrays with an even number of elements, returns the average of the two
* middle elements.
*
* @param values the array of integers to find the median of (can be unsorted)
* @return the median value as a double
* @throws IllegalArgumentException if the input array is empty or null
*/
public static double median(int[] values) {
if (values == null || values.length == 0) {
Expand All @@ -22,6 +40,10 @@ public static double median(int[] values) {

Arrays.sort(values);
int length = values.length;
return length % 2 == 0 ? (values[length / 2] + values[length / 2 - 1]) / 2.0 : values[length / 2];
if (length % 2 == 0) {
return (values[length / 2] + values[length / 2 - 1]) / 2.0;
} else {
return values[length / 2];
}
}
}
127 changes: 120 additions & 7 deletions src/test/java/com/thealgorithms/maths/MedianTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,153 @@

import org.junit.jupiter.api.Test;

public class MedianTest {
/**
* Test class for {@link Median}.
* Tests various scenarios including edge cases, odd/even length arrays,
* negative values, and unsorted inputs.
*/
class MedianTest {

@Test
void medianSingleValue() {
void testMedianSingleValue() {
int[] arr = {0};
assertEquals(0, Median.median(arr));
}

@Test
void medianTwoValues() {
void testMedianSinglePositiveValue() {
int[] arr = {42};
assertEquals(42, Median.median(arr));
}

@Test
void testMedianSingleNegativeValue() {
int[] arr = {-15};
assertEquals(-15, Median.median(arr));
}

@Test
void testMedianTwoValues() {
int[] arr = {1, 2};
assertEquals(1.5, Median.median(arr));
}

@Test
void medianThreeValues() {
void testMedianTwoIdenticalValues() {
int[] arr = {5, 5};
assertEquals(5.0, Median.median(arr));
}

@Test
void testMedianThreeValues() {
int[] arr = {1, 2, 3};
assertEquals(2, Median.median(arr));
}

@Test
void medianDecimalValueReturn() {
void testMedianThreeUnsortedValues() {
int[] arr = {3, 1, 2};
assertEquals(2, Median.median(arr));
}

@Test
void testMedianDecimalValueReturn() {
int[] arr = {1, 2, 3, 4, 5, 6, 8, 9};
assertEquals(4.5, Median.median(arr));
}

@Test
void medianNegativeValues() {
void testMedianNegativeValues() {
int[] arr = {-27, -16, -7, -4, -2, -1};
assertEquals(-5.5, Median.median(arr));
}

@Test
void medianEmptyArrayThrows() {
void testMedianMixedPositiveAndNegativeValues() {
int[] arr = {-10, -5, 0, 5, 10};
assertEquals(0, Median.median(arr));
}

@Test
void testMedianMixedUnsortedValues() {
int[] arr = {10, -5, 0, 5, -10};
assertEquals(0, Median.median(arr));
}

@Test
void testMedianLargeOddArray() {
int[] arr = {9, 7, 5, 3, 1, 2, 4, 6, 8};
assertEquals(5, Median.median(arr));
}

@Test
void testMedianLargeEvenArray() {
int[] arr = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
assertEquals(55.0, Median.median(arr));
}

@Test
void testMedianAllSameValues() {
int[] arr = {7, 7, 7, 7, 7};
assertEquals(7.0, Median.median(arr));
}

@Test
void testMedianWithZeros() {
int[] arr = {0, 0, 0, 0, 0};
assertEquals(0.0, Median.median(arr));
}

@Test
void testMedianAlreadySorted() {
int[] arr = {1, 2, 3, 4, 5};
assertEquals(3, Median.median(arr));
}

@Test
void testMedianReverseSorted() {
int[] arr = {5, 4, 3, 2, 1};
assertEquals(3, Median.median(arr));
}

@Test
void testMedianWithDuplicates() {
int[] arr = {1, 2, 2, 3, 3, 3, 4};
assertEquals(3, Median.median(arr));
}

@Test
void testMedianEmptyArrayThrows() {
int[] arr = {};
assertThrows(IllegalArgumentException.class, () -> Median.median(arr));
}

@Test
void testMedianNullArrayThrows() {
assertThrows(IllegalArgumentException.class, () -> Median.median(null));
}

@Test
void testMedianExtremeValues() {
int[] arr = {Integer.MAX_VALUE, Integer.MIN_VALUE};
assertEquals(-0.5, Median.median(arr));
}

@Test
void testMedianTwoNegativeValues() {
int[] arr = {-10, -20};
assertEquals(-15.0, Median.median(arr));
}

@Test
void testMedianFourValuesEven() {
int[] arr = {1, 2, 3, 4};
assertEquals(2.5, Median.median(arr));
}

@Test
void testMedianFiveValuesOdd() {
int[] arr = {10, 20, 30, 40, 50};
assertEquals(30.0, Median.median(arr));
}
}