Skip to content

Commit 0669834

Browse files
committed
feat: add LibrarySort implementation
1 parent b3fcb12 commit 0669834

2 files changed

Lines changed: 127 additions & 0 deletions

File tree

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.thealgorithms.sorts;
2+
3+
/**
4+
* Library Sort (also known as Gapped Insertion Sort) is traditionally implemented
5+
* using periodic gaps between elements for faster insertion. This implementation
6+
* uses binary search to find the insertion position combined with array shifting,
7+
* which is a simplified variant without gap-based optimization.
8+
* Time Complexity: O(n^2) worst case due to element shifting
9+
* Space Complexity: O(n)
10+
*
11+
* @see <a href="https://en.wikipedia.org/wiki/Library_sort">
12+
* Wikipedia: Library Sort</a>
13+
* @author Vraj Prajapati (@Rosander0)
14+
*/
15+
public final class LibrarySort {
16+
17+
private LibrarySort() {
18+
// Utility class
19+
}
20+
21+
/**
22+
* Sorts an array using the Library Sort algorithm.
23+
*
24+
* @param array the array to sort (must not be null)
25+
* @return the sorted array
26+
* @throws IllegalArgumentException if {@code array} is {@code null}
27+
*/
28+
public static int[] sort(final int[] array) {
29+
if (array == null) {
30+
throw new IllegalArgumentException("Input array must not be null.");
31+
}
32+
if (array.length <= 1) {
33+
return array;
34+
}
35+
36+
int n = array.length;
37+
Integer[] spaced = new Integer[2 * n];
38+
39+
spaced[0] = array[0];
40+
int inserted = 1;
41+
42+
for (int i = 1; i < n; i++) {
43+
int pos = binarySearch(spaced, inserted, array[i]);
44+
for (int j = inserted; j > pos; j--) {
45+
spaced[j] = spaced[j - 1];
46+
}
47+
spaced[pos] = array[i];
48+
inserted++;
49+
}
50+
51+
int idx = 0;
52+
for (int i = 0; i < 2 * n; i++) {
53+
if (spaced[i] != null) {
54+
array[idx++] = spaced[i];
55+
}
56+
}
57+
return array;
58+
}
59+
60+
/**
61+
* Binary search to find insertion position among inserted elements.
62+
*
63+
* @param spaced the spaced array
64+
* @param inserted number of elements inserted so far
65+
* @param target the value to find position for
66+
* @return the correct insertion index
67+
*/
68+
private static int binarySearch(final Integer[] spaced,
69+
final int inserted, final int target) {
70+
int lo = 0;
71+
int hi = inserted;
72+
while (lo < hi) {
73+
int mid = lo + (hi - lo) / 2;
74+
if (spaced[mid] <= target) {
75+
lo = mid + 1;
76+
} else {
77+
hi = mid;
78+
}
79+
}
80+
return lo;
81+
}
82+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.thealgorithms.sorts;
2+
// author: Vraj Prajapati @Rosander0
3+
4+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
public class LibrarySortTest {
10+
11+
@Test
12+
public void testBasicSort() {
13+
assertArrayEquals(new int[] {1, 2, 3, 4, 5}, LibrarySort.sort(new int[] {5, 3, 1, 4, 2}));
14+
}
15+
16+
@Test
17+
public void testAlreadySorted() {
18+
assertArrayEquals(new int[] {1, 2, 3, 4, 5}, LibrarySort.sort(new int[] {1, 2, 3, 4, 5}));
19+
}
20+
21+
@Test
22+
public void testReverseSorted() {
23+
assertArrayEquals(new int[] {1, 2, 3, 4, 5}, LibrarySort.sort(new int[] {5, 4, 3, 2, 1}));
24+
}
25+
26+
@Test
27+
public void testDuplicates() {
28+
assertArrayEquals(new int[] {1, 2, 2, 3, 3}, LibrarySort.sort(new int[] {3, 2, 1, 3, 2}));
29+
}
30+
31+
@Test
32+
public void testSingleElement() {
33+
assertArrayEquals(new int[] {1}, LibrarySort.sort(new int[] {1}));
34+
}
35+
36+
@Test
37+
public void testEmptyArray() {
38+
assertArrayEquals(new int[] {}, LibrarySort.sort(new int[] {}));
39+
}
40+
41+
@Test
42+
public void testNullArray() {
43+
assertThrows(IllegalArgumentException.class, () -> LibrarySort.sort(null));
44+
}
45+
}

0 commit comments

Comments
 (0)