-
Notifications
You must be signed in to change notification settings - Fork 20.6k
Add AmericanFlagSort algorithm #6662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
c4597f3
cb9903f
7002ff8
2f965e0
39f73ef
4c9c292
5622c71
bed823e
38712b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package com.thealgorithms.sorts; | ||
|
||
/** | ||
* American Flag Sort Algorithm Implementation | ||
* This implementation uses a bucket-based approach that works with all Comparable types | ||
* | ||
* @see <a href="https://en.wikipedia.org/wiki/American_flag_sort">American Flag Sort Algorithm</a> | ||
*/ | ||
public class AmericanFlagSort implements SortAlgorithm { | ||
|
||
@Override | ||
public <T extends Comparable<T>> T[] sort(T[] array) { | ||
if (array == null || array.length <= 1) { | ||
return array; | ||
} | ||
|
||
// For generic comparable types, use a simplified bucket sort approach | ||
bucketSort(array, 0, array.length - 1); | ||
return array; | ||
} | ||
|
||
private <T extends Comparable<T>> void bucketSort(T[] array, int start, int end) { | ||
if (start >= end) { | ||
return; | ||
} | ||
|
||
// Find min and max values for partitioning | ||
T min = array[start]; | ||
T max = array[start]; | ||
|
||
for (int i = start + 1; i <= end; i++) { | ||
if (SortUtils.less(array[i], min)) { | ||
min = array[i]; | ||
} | ||
if (SortUtils.greater(array[i], max)) { | ||
max = array[i]; | ||
} | ||
} | ||
|
||
// If all elements are equal, no need to sort | ||
if (min.compareTo(max) == 0) { | ||
return; | ||
} | ||
|
||
// Use a 3-way partitioning approach similar to American Flag Sort | ||
int length = end - start + 1; | ||
if (length < 10) { | ||
// For small arrays, use insertion sort | ||
insertionSort(array, start, end); | ||
return; | ||
} | ||
|
||
// Partition into buckets based on comparison with pivot | ||
T pivot = array[start + length / 2]; | ||
|
||
int lt = start; // less than pivot | ||
int gt = end; // greater than pivot | ||
int i = start; // current element | ||
|
||
while (i <= gt) { | ||
int cmp = array[i].compareTo(pivot); | ||
if (cmp < 0) { | ||
SortUtils.swap(array, lt++, i++); | ||
} else if (cmp > 0) { | ||
SortUtils.swap(array, i, gt--); | ||
} else { | ||
i++; | ||
} | ||
} | ||
|
||
// Recursively sort the partitions | ||
bucketSort(array, start, lt - 1); | ||
bucketSort(array, gt + 1, end); | ||
} | ||
|
||
private <T extends Comparable<T>> void insertionSort(T[] array, int start, int end) { | ||
for (int i = start + 1; i <= end; i++) { | ||
T key = array[i]; | ||
int j = i - 1; | ||
|
||
while (j >= start && SortUtils.greater(array[j], key)) { | ||
array[j + 1] = array[j]; | ||
j--; | ||
} | ||
array[j + 1] = key; | ||
} | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding explicit test cases for small arrays, already sorted arrays, reverse-sorted arrays, duplicates, and empty arrays to ensure correctness. You may want to add tests for null arrays or arrays with a single element to confirm that the algorithm handles these gracefully. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.thealgorithms.sorts; | ||
|
||
public class AmericanFlagSortTest extends SortingAlgorithmTest { | ||
@Override | ||
SortAlgorithm getSortAlgorithm() { | ||
return new AmericanFlagSort(); | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.