From 66430d5a8a9c0098688aaf6f7cbcc312e34e3b7f Mon Sep 17 00:00:00 2001 From: Speiger Date: Mon, 30 Nov 2020 00:11:40 +0100 Subject: [PATCH] Added Sorting Algorythms. -Added: Quicksort, MergeSort, MemFreeMergeSort, InsertionSort, SelectionSort. -Started: ParallelQuickSort. --- .../src/builder/example/ClassType.java | 7 +- .../src/builder/example/GlobalVariables.java | 43 +- .../src/builder/example/TestBuilder.java | 1 + .../src/builder/mappers/LineMapper.java | 43 ++ .../speiger/src/builder/misc/RegexUtil.java | 9 + .../collections/AbstractCollection.template | 19 +- .../templates/collections/Collection.template | 8 +- .../templates/functions/Comparator.template | 12 + .../templates/lists/AbstractList.template | 44 ++ .../templates/lists/ArrayList.template | 230 +++++++++- .../collections/templates/lists/List.template | 34 +- .../templates/utils/Arrays.template | 423 +++++++++++++++++- 12 files changed, 837 insertions(+), 36 deletions(-) create mode 100644 src/main/java/speiger/src/builder/mappers/LineMapper.java create mode 100644 src/main/resources/speiger/assets/collections/templates/functions/Comparator.template diff --git a/src/main/java/speiger/src/builder/example/ClassType.java b/src/main/java/speiger/src/builder/example/ClassType.java index 18d6f14..0bba91e 100644 --- a/src/main/java/speiger/src/builder/example/ClassType.java +++ b/src/main/java/speiger/src/builder/example/ClassType.java @@ -3,7 +3,7 @@ package speiger.src.builder.example; public enum ClassType { BOOLEAN("boolean", "Boolean", "Boolean", "booleans", "BOOLEAN", "false"), - BYTE("byte", "Byte", "Byte", "bytes", "BYTES", "(byte)0"), + BYTE("byte", "Byte", "Byte", "bytes", "BYTE", "(byte)0"), SHORT("short", "Short", "Short", "shorts", "SHORT", "(short)0"), CHAR("char", "Character", "Char", "chars", "CHAR", "(char)0"), INT("int", "Integer", "Int", "ints", "INT", "0"), @@ -64,6 +64,11 @@ public enum ClassType return emptyValue; } + public boolean isObject() + { + return this == OBJECT; + } + public boolean isPrimitiveBlocking() { return this == BOOLEAN || this == OBJECT; diff --git a/src/main/java/speiger/src/builder/example/GlobalVariables.java b/src/main/java/speiger/src/builder/example/GlobalVariables.java index 6926889..710f111 100644 --- a/src/main/java/speiger/src/builder/example/GlobalVariables.java +++ b/src/main/java/speiger/src/builder/example/GlobalVariables.java @@ -9,6 +9,7 @@ import java.util.function.UnaryOperator; import speiger.src.builder.mappers.ArgumentMapper; import speiger.src.builder.mappers.InjectMapper; +import speiger.src.builder.mappers.LineMapper; import speiger.src.builder.mappers.SimpleMapper; import speiger.src.builder.processor.TemplateProcess; @@ -26,12 +27,15 @@ public class GlobalVariables public GlobalVariables createVariables() { addSimpleMapper("PACKAGE", type.getPathType()); + addDeprication("@Primitive"); addSimpleMapper("CLASS_TYPE", type.getClassType()); addSimpleMapper("KEY_TYPE", type.getKeyType()); addSimpleMapper("EMPTY_VALUE", type.getEmptyValue()); - addSimpleMapper(" KEY_GENERIC_TYPE", type == ClassType.OBJECT ? "<"+type.getKeyType()+">" : ""); - addSimpleMapper(" GENERIC_BRACES", type == ClassType.OBJECT ? " <"+type.getKeyType()+">" : ""); - addSimpleMapper("BRACES", type == ClassType.OBJECT ? "<>" : ""); + addSimpleMapper(" KEY_GENERIC_TYPE", type.isObject() ? "<"+type.getKeyType()+">" : ""); + addSimpleMapper(" KEY_COMPAREABLE_TYPE", type.isObject() ? "<"+type.getKeyType()+" extends Comparable>" : ""); + addSimpleMapper(" GENERIC_BRACES", type.isObject() ? " <"+type.getKeyType()+">" : ""); + addSimpleMapper(" COMPAREABLE_BRACES", type.isObject() ? " <"+type.getKeyType()+" extends Comparable>" : ""); + addSimpleMapper("BRACES", type.isObject() ? "<>" : ""); if(type.needsCustomJDKType()) { addSimpleMapper("JAVA_TYPE", type.getCustomJDKType().getKeyType()); @@ -42,11 +46,14 @@ public class GlobalVariables public GlobalVariables createHelperVariables() { - addArgumentMapper("EQUALS_KEY_TYPE", type == ClassType.OBJECT ? "Objects.equals(%1$s, %2$s)" : "Objects.equals(KEY_TO_OBJ(%1$s), %2$s)").removeBraces(); + addArgumentMapper("EQUALS_KEY_TYPE", type.isObject() ? "Objects.equals(%1$s, %2$s)" : "Objects.equals(KEY_TO_OBJ(%1$s), %2$s)").removeBraces(); addArgumentMapper("EQUALS", type.getEquals()).removeBraces(); - addSimpleMapper("KEY_TO_OBJ", type.getClassType()+".valueOf"); - addInjectMapper("OBJ_TO_KEY", type == ClassType.OBJECT ? "%s" : "%s."+type.getKeyType()+"Value()").removeBraces(); + addArgumentMapper("COMPARE_TO", type.isObject() ? "%1$s.compareTo(%2$s)" : type.getClassType()+".compare(%1$s, %2$s)").removeBraces(); + addInjectMapper("KEY_TO_OBJ", type.isObject() ? "%s" : type.getClassType()+".valueOf(%s)").removeBraces(); + addInjectMapper("OBJ_TO_KEY", type.isObject() ? "%s" : "%s."+type.getKeyType()+"Value()").removeBraces(); addInjectMapper("CLASS_TO_KEY", "(("+type.getClassType()+")%s)."+type.getKeyType()+"Value()").removeBraces(); + addSimpleMapper("APPLY", "applyAs"+type.getCustomJDKType().getNonFileType()); + addInjectMapper("HASH", type.getClassType()+".hashCode(%s)").removeBraces(); return this; } @@ -54,7 +61,17 @@ public class GlobalVariables { addSimpleMapper("JAVA_PREDICATE", type.isPrimitiveBlocking() ? "" : type.getCustomJDKType().getFileType()+"Predicate"); addSimpleMapper("JAVA_CONSUMER", type.isPrimitiveBlocking() ? "" : "java.util.function."+type.getCustomJDKType().getFileType()+"Consumer"); - addClassMapper("CONSUMER", "Consumer"); + addSimpleMapper("UNARY_OPERATOR", type.isPrimitiveBlocking() ? "" : type == ClassType.BOOLEAN ? "BinaryOperator" : type.getCustomJDKType().getFileType()+"UnaryOperator"); + if(type.isObject()) + { + addSimpleMapper("CONSUMER", "Consumer"); + addSimpleMapper("COMPARATOR", "Comparator"); + } + else + { + addClassMapper("CONSUMER", "Consumer"); + addClassMapper("COMPARATOR", "Comparator"); + } addClassMapper("ITERATORS", "Iterators"); addClassMapper("BI_ITERATOR", "BidirectionalIterator"); addClassMapper("LIST_ITERATOR", "ListIterator"); @@ -84,6 +101,7 @@ public class GlobalVariables addFunctionMapper("POP", "pop"); addFunctionMapper("PUSH", "push"); addFunctionMapper("TOP", "top"); + addFunctionMappers("REPLACE", "replace%ss"); return this; } @@ -125,11 +143,22 @@ public class GlobalVariables operators.add(new SimpleMapper(pattern, replacement+type.getNonFileType())); } + private void addFunctionMappers(String pattern, String replacement) + { + operators.add(new SimpleMapper(pattern, String.format(replacement, type.getNonFileType()))); + } + private void addSimpleMapper(String pattern, String replacement) { operators.add(new SimpleMapper(pattern, replacement)); } + private void addDeprication(String pattern) + { + if(type == ClassType.OBJECT) operators.add(new LineMapper(pattern)); + else operators.add(new SimpleMapper(pattern, "@Deprecated")); + } + private InjectMapper addInjectMapper(String pattern, String replacement) { InjectMapper mapper = new InjectMapper(pattern, replacement); diff --git a/src/main/java/speiger/src/builder/example/TestBuilder.java b/src/main/java/speiger/src/builder/example/TestBuilder.java index ef5f1fc..2ca13c3 100644 --- a/src/main/java/speiger/src/builder/example/TestBuilder.java +++ b/src/main/java/speiger/src/builder/example/TestBuilder.java @@ -51,6 +51,7 @@ public class TestBuilder extends TemplateProcessor varibles.add(type); } blocked.put("Consumer", EnumSet.of(ClassType.OBJECT)); + blocked.put("Comparator", EnumSet.of(ClassType.OBJECT)); blocked.put("Stack", EnumSet.of(ClassType.OBJECT)); } diff --git a/src/main/java/speiger/src/builder/mappers/LineMapper.java b/src/main/java/speiger/src/builder/mappers/LineMapper.java new file mode 100644 index 0000000..d908b61 --- /dev/null +++ b/src/main/java/speiger/src/builder/mappers/LineMapper.java @@ -0,0 +1,43 @@ +package speiger.src.builder.mappers; + +import java.util.function.UnaryOperator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import speiger.src.builder.misc.RegexUtil; + +public class LineMapper implements UnaryOperator +{ + Pattern pattern; + + public LineMapper(String pattern) + { + this.pattern = Pattern.compile(pattern, Pattern.LITERAL); + } + + @Override + public String apply(String t) + { + Matcher matcher = pattern.matcher(t); + if(matcher.find()) + { + StringBuffer buffer = new StringBuffer(); + do + { + int start = matcher.end() - 1; + int[] result = RegexUtil.findFullLine(t, start); + if(result != null) + { + matcher.appendReplacement(buffer, pattern.pattern()); + buffer.setLength(buffer.length() - (start - result[0])); + RegexUtil.skip(matcher, result[1] - start); + } + } while (matcher.find()); + matcher.appendTail(buffer); + return buffer.toString(); + } + return t; + } + + +} diff --git a/src/main/java/speiger/src/builder/misc/RegexUtil.java b/src/main/java/speiger/src/builder/misc/RegexUtil.java index 5a21c66..75e096f 100644 --- a/src/main/java/speiger/src/builder/misc/RegexUtil.java +++ b/src/main/java/speiger/src/builder/misc/RegexUtil.java @@ -52,6 +52,15 @@ public class RegexUtil return ""; } + public static int[] findFullLine(String s, int startIndex) + { + int offset = s.indexOf("\n", startIndex); + if(offset == -1) return null; + int start = s.lastIndexOf("\n", startIndex); + if(start == -1) return null; + return new int[]{start, offset}; + } + static { try diff --git a/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template b/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template index 5577893..1f3eb1a 100644 --- a/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template +++ b/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template @@ -1,8 +1,6 @@ package speiger.src.collections.PACKAGE.collections; -#if !TYPE_OBJECT import java.util.Collection; -#endif import java.util.AbstractCollection; import speiger.src.collections.PACKAGE.collections.COLLECTION; @@ -42,24 +40,28 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle } @Override + @Deprecated public boolean containsAll(Collection c) { return c instanceof COLLECTION ? containsAll((COLLECTION)c) : super.containsAll(c); } @Override + @Deprecated public boolean addAll(Collection c) { return c instanceof COLLECTION ? addAll((COLLECTION)c) : super.addAll(c); } @Override + @Deprecated public boolean removeAll(Collection c) { return c instanceof COLLECTION ? removeAll((COLLECTION)c) : super.removeAll(c); } @Override + @Deprecated public boolean retainAll(Collection c) { return c instanceof COLLECTION ? retainAll((COLLECTION)c) : super.retainAll(c); @@ -81,6 +83,17 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle return false; } +#endif + @Override + @Primitive + public boolean containsAny(Collection c) { + for(KEY_TYPE e : this) + if(contains(KEY_TO_OBJ(e))) + return true; + return false; + } + +#if !TYPE_OBJECT @Override @Deprecated public boolean remove(Object e) { return COLLECTION.super.remove(e); } @@ -120,10 +133,12 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle return modified; } + @Override public KEY_TYPE[] TO_ARRAY() { return TO_ARRAY(new KEY_TYPE[size()]); } + @Override public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) { if(a == null || a.length < size()) a = new KEY_TYPE[size()]; ITERATORS.unwrap(a, iterator()); diff --git a/src/main/resources/speiger/assets/collections/templates/collections/Collection.template b/src/main/resources/speiger/assets/collections/templates/collections/Collection.template index ae85d52..24e8e59 100644 --- a/src/main/resources/speiger/assets/collections/templates/collections/Collection.template +++ b/src/main/resources/speiger/assets/collections/templates/collections/Collection.template @@ -18,9 +18,13 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection, ITE public boolean contains(KEY_TYPE o); public boolean containsAll(COLLECTION c); - + public boolean containsAny(COLLECTION c); +#endif + public boolean containsAny(Collection c); + +#if !TYPE_OBJECT public boolean REMOVE_KEY(KEY_TYPE o); public boolean removeAll(COLLECTION c); @@ -56,7 +60,7 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection, ITE @Override @Deprecated - public default boolean remove(Object o) { return o != null && remove(CLASS_TO_KEY(o)); } + public default boolean remove(Object o) { return o != null && REMOVE_KEY(CLASS_TO_KEY(o)); } #endif @Override diff --git a/src/main/resources/speiger/assets/collections/templates/functions/Comparator.template b/src/main/resources/speiger/assets/collections/templates/functions/Comparator.template new file mode 100644 index 0000000..29985e7 --- /dev/null +++ b/src/main/resources/speiger/assets/collections/templates/functions/Comparator.template @@ -0,0 +1,12 @@ +package speiger.src.collections.PACKAGE.functions; + +import java.util.Comparator; + +public interface COMPARATOR extends Comparator +{ + int compare(KEY_TYPE o1, KEY_TYPE o2); + + default int compare(CLASS_TYPE o1, CLASS_TYPE o2) { + return compare(OBJ_TO_KEY(o1), OBJ_TO_KEY(o2)); + } +} \ No newline at end of file diff --git a/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template b/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template index b4222ea..36918db 100644 --- a/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template +++ b/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template @@ -1,6 +1,8 @@ package speiger.src.collections.PACKAGE.lists; import java.util.Collection; +import java.util.List; +import java.util.ListIterator; import java.util.Objects; import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION; @@ -97,6 +99,48 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION } #endif + @Override + public boolean equals(Object o) { + if (o == this) + return true; + if (!(o instanceof List)) + return false; + List l = (List)o; + if(l.size() != size()) return false; +#if !TYPE_OBJECT + if(l instanceof LIST) + { + LIST_ITERATOR e1 = listIterator(); + LIST_ITERATOR e2 = ((LIST)l).listIterator(); + while (e1.hasNext() && e2.hasNext()) { + if(!(EQUALS(e1.NEXT(), e2.NEXT()))) + return false; + } + return !(e1.hasNext() || e2.hasNext()); + } +#endif + ListIterator e1 = listIterator(); + ListIterator e2 = l.listIterator(); + while (e1.hasNext() && e2.hasNext()) { + if(!Objects.equals(e1.next(), e2.next())) + return false; + } + return !(e1.hasNext() || e2.hasNext()); + } + + @Override + public int hashCode() { + int hashCode = 1; + LIST_ITERATOR KEY_GENERIC_TYPE i = listIterator(); + while(i.hasNext()) +#if TYPE_OBJECT + hashCode = 31 * hashCode + i.next().hashCode(); +#else + hashCode = 31 * hashCode + HASH(i.NEXT()); +#endif + return hashCode; + } + @Override public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) { return new SUB_LIST(this, fromIndex, toIndex); diff --git a/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template b/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template index 6ef6800..2e9dc27 100644 --- a/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template +++ b/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template @@ -3,6 +3,11 @@ package speiger.src.collections.PACKAGE.lists; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; +import java.util.Objects; +import java.util.function.Predicate; +#if PRIMITIVES +import java.util.function.JAVA_PREDICATE; +#endif import speiger.src.collections.PACKAGE.collections.COLLECTION; #if !TYPE_OBJECT @@ -13,6 +18,8 @@ import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ITERATORS; #if TYPE_OBJECT import speiger.src.collections.utils.Stack; +#else +import speiger.src.collections.objects.utils.ObjectArrays; #endif import speiger.src.collections.utils.IArray; import speiger.src.collections.utils.SanityChecks; @@ -103,6 +110,11 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE return true; } + @Override + public void PUSH(KEY_TYPE e) { + add(e); + } + #if !TYPE_OBJECT @Override public void add(int index, KEY_TYPE e) { @@ -115,6 +127,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE #endif @Override + @Primitive public boolean addAll(int index, Collection c) { if(c instanceof COLLECTION) return addAll(index, (COLLECTION KEY_GENERIC_TYPE)c); int add = c.size(); @@ -211,6 +224,61 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE return a; } +#endif + @Override + @Primitive + public boolean containsAll(Collection c) { +#if !TYPE_OBJECT + if(c instanceof COLLECTION) return containsAll((COLLECTION)c); +#endif + Objects.requireNonNull(c); + for(int i = 0,m=size;i c) + { +#if !TYPE_OBJECT + if(c instanceof COLLECTION) return containsAny((COLLECTION)c); +#endif + Objects.requireNonNull(c); + for(int i = 0,m=size;i c) { + if(c.isEmpty()) return false; +#if !TYPE_OBJECT + if(c instanceof COLLECTION) return removeAll((COLLECTION)c); +#endif + boolean modified = false; + for(int i = 0, j = 0;i c) { + if(c.isEmpty()) { + boolean modifed = size > 0; + Arrays.fill(data, 0, size, EMPTY_VALUE); + size = 0; + return modifed; + } +#if !TYPE_OBJECT + if(c instanceof COLLECTION) return retainAll((COLLECTION)c); +#endif + boolean modified = false; + for(int i = 0, j = 0;i filter) { + Objects.requireNonNull(filter); + boolean modified = false; + for(int i = 0, j = 0;i 0; + Arrays.fill(data, 0, size, EMPTY_VALUE); + size = 0; + return modifed; + } + boolean modified = false; + for(int i = 0, j = 0;i E[] toArray(E[] a) { + if(a == null) a = (E[])new Object[size]; + else if(a.length < size) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size); + for(int i = 0;i> 1), SanityChecks.MAX_ARRAY_SIZE), capacity)); } diff --git a/src/main/resources/speiger/assets/collections/templates/lists/List.template b/src/main/resources/speiger/assets/collections/templates/lists/List.template index 1b8a3e3..0cf8630 100644 --- a/src/main/resources/speiger/assets/collections/templates/lists/List.template +++ b/src/main/resources/speiger/assets/collections/templates/lists/List.template @@ -1,11 +1,18 @@ package speiger.src.collections.PACKAGE.lists; import java.util.List; +#if !TYPE_OBJECT && !TYPE_BOOLEAN +import java.util.Objects; +import java.util.function.UNARY_OPERATOR; +import java.util.function.UnaryOperator; +#endif + import speiger.src.collections.PACKAGE.collections.COLLECTION; public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List { #if !TYPE_OBJECT + @Override public boolean add(KEY_TYPE e); public void add(int index, KEY_TYPE e); @@ -27,9 +34,21 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List public int indexOf(KEY_TYPE e); public int lastIndexOf(KEY_TYPE e); + +#if !TYPE_BOOLEAN + public default void REPLACE(UNARY_OPERATOR o) { + Objects.requireNonNull(o); + LIST_ITERATOR iter = listIterator(); + while (iter.hasNext()) +#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT + iter.set((KEY_TYPE)o.APPLY(iter.NEXT())); +#else + iter.set(o.APPLY(iter.NEXT())); +#endif + } #endif - +#endif public default void addElements(int from, KEY_TYPE[] a) { addElements(from, a, 0, a.length); } public void addElements(int from, KEY_TYPE[] a, int offset, int length); @@ -106,5 +125,18 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List public default CLASS_TYPE remove(int index) { return KEY_TO_OBJ(REMOVE(index)); } + +#if !TYPE_BOOLEAN + @Override + @Deprecated + public default void replaceAll(UnaryOperator o) { + Objects.requireNonNull(o); +#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT + REPLACE(T -> OBJ_TO_KEY(o.apply(KEY_TO_OBJ((KEY_TYPE)T)))); +#else + REPLACE(T -> OBJ_TO_KEY(o.apply(KEY_TO_OBJ(T)))); +#endif + } +#endif #endif } \ No newline at end of file diff --git a/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template b/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template index 82bc146..1aeafdc 100644 --- a/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template +++ b/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template @@ -1,20 +1,48 @@ package speiger.src.collections.PACKAGE.utils; +import java.util.Arrays; +import java.util.concurrent.RecursiveAction; + +#if !TYPE_OBJECT +import speiger.src.collections.PACKAGE.functions.COMPARATOR; +import speiger.src.collections.utils.SanityChecks; +#else +import java.util.Comparator; +#endif + public class ARRAYS { #if !TYPE_OBJECT public static final KEY_TYPE[] EMPTY_ARRAY = new KEY_TYPE[0]; public static CLASS_TYPE[] wrap(KEY_TYPE[] a) { - CLASS_TYPE[] result = new CLASS_TYPE[a.length]; - for(int i = 0,m=a.length;i= from && comp.compare(current, array[j]) < 0) { + array[j+1] = array[j--]; + } + array[j+1] = current; + } + } + + public static COMPAREABLE_BRACES void insertionSort(KEY_TYPE[] array) { + insertionSort(array, 0, array.length); + } + + public static COMPAREABLE_BRACES void insertionSort(KEY_TYPE[] array, int length) { + insertionSort(array, 0, length); + } + + public static COMPAREABLE_BRACES void insertionSort(KEY_TYPE[] array, int from, int to) { + for (int i = from+1;i= from && COMPARE_TO(current, array[j]) < 0) { + array[j+1] = array[j--]; + } + array[j+1] = current; + } + } + + public static GENERIC_BRACES void selectionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { + selectionSort(array, 0, array.length, comp); + } + + public static GENERIC_BRACES void selectionSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { + selectionSort(array, 0, length, comp); + } + + public static GENERIC_BRACES void selectionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { + for (int i = from; i < to; i++) { + KEY_TYPE min = array[i]; + int minId = i; + for(int j = i+1; j < to; j++) { + if(comp.compare(array[j], min) < 0) { + min = array[j]; + minId = j; + } + } + KEY_TYPE temp = array[i]; + array[i] = min; + array[minId] = temp; + } + } + + public static COMPAREABLE_BRACES void selectionSort(KEY_TYPE[] array) { + selectionSort(array, 0, array.length); + } + + public static COMPAREABLE_BRACES void selectionSort(KEY_TYPE[] array, int length) { + selectionSort(array, 0, length); + } + + public static COMPAREABLE_BRACES void selectionSort(KEY_TYPE[] array, int from, int to) { + for (int i = from; i < to; i++) { + KEY_TYPE min = array[i]; + int minId = i; + for(int j = i+1; j < to; j++) { + if(COMPARE_TO(array[j], min) < 0) { + min = array[j]; + minId = j; + } + } + KEY_TYPE temp = array[i]; + array[i] = min; + array[minId] = temp; + } + } + + public static GENERIC_BRACES void mergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { + mergeSort(array, null, 0, array.length, comp); + } + + public static GENERIC_BRACES void mergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { + mergeSort(array, null, 0, length, comp); + } + + public static GENERIC_BRACES void mergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { + if(to - from < 16) { + insertionSort(array, from, to, comp); + return; + } + if(supp == null) supp = Arrays.copyOf(array, to); + int mid = (from + to) >>> 1; + mergeSort(supp, array, from, mid, comp); + mergeSort(supp, array, mid, to, comp); + if(comp.compare(supp[mid - 1], supp[mid]) <= 0) + { + System.arraycopy(supp, from, array, from, to - from); + return; + } + for(int p = from, q = mid;from < to;from++) { + if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) array[from] = supp[p++]; + else array[from] = supp[q++]; + } + } + + public static COMPAREABLE_BRACES void mergeSort(KEY_TYPE[] array) { + mergeSort(array, null, 0, array.length); + } + + public static COMPAREABLE_BRACES void mergeSort(KEY_TYPE[] array, int length) { + mergeSort(array, null, 0, length); + } + + public static COMPAREABLE_BRACES void mergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to) { + if(to - from < 16) { + insertionSort(array, from, to); + return; + } + if(supp == null) supp = Arrays.copyOf(array, to); + int mid = (from + to) >>> 1; + mergeSort(supp, array, from, mid); + mergeSort(supp, array, mid, to); + if(COMPARE_TO(supp[mid - 1], supp[mid]) <= 0) + { + System.arraycopy(supp, from, array, from, to - from); + return; + } + for(int p = from, q = mid;from < to;from++) { + if(q >= to || p < mid && COMPARE_TO(supp[p], supp[q]) < 0) array[from] = supp[p++]; + else array[from] = supp[q++]; + } + } + + public static GENERIC_BRACES void memFreeMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { + memFreeMergeSort(array, 0, array.length, comp); + } + + public static GENERIC_BRACES void memFreeMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { + memFreeMergeSort(array, 0, length, comp); + } + + public static GENERIC_BRACES void memFreeMergeSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { + if(to - from < 16) { + insertionSort(array, from, to, comp); + return; + } + int mid = (from + to) >>> 1; + memFreeMergeSort(array, from, mid, comp); + memFreeMergeSort(array, mid, to, comp); + if(comp.compare(array[mid - 1], array[mid]) <= 0) + return; + for(int i = from, j = mid, compare;i < j && j < to;) { + if((compare = comp.compare(array[i], array[j])) < 0) + i++; + else if(compare == 0) swap(array, ++i, j); + else { + swap(array, i++, j); + int k = j; + for(;k < to - 1 && comp.compare(array[j], array[k + 1]) > 0;k++); + if(j == k) + continue; + KEY_TYPE value = array[j]; + System.arraycopy(array, j + 1, array, j, k - j); + array[k] = value; + } + } + } + + public static COMPAREABLE_BRACES void memFreeMergeSort(KEY_TYPE[] array) { + memFreeMergeSort(array, 0, array.length); + } + + public static COMPAREABLE_BRACES void memFreeMergeSort(KEY_TYPE[] array, int length) { + memFreeMergeSort(array, 0, length); + } + + public static COMPAREABLE_BRACES void memFreeMergeSort(KEY_TYPE[] array, int from, int to) { + if(to - from < 16) { + insertionSort(array, from, to); + return; + } + int mid = (from + to) >>> 1; + memFreeMergeSort(array, from, mid); + memFreeMergeSort(array, mid, to); + if(COMPARE_TO(array[mid - 1], array[mid]) <= 0) + return; + for(int i = from, j = mid, comp;i < j && j < to;) { + if((comp = COMPARE_TO(array[i], array[j])) < 0) + i++; + else if(comp == 0) swap(array, ++i, j); + else { + swap(array, i++, j); + int k = j; + for(;k < to - 1 && COMPARE_TO(array[j], array[k + 1]) > 0;k++); + if(j == k) + continue; + KEY_TYPE value = array[j]; + System.arraycopy(array, j + 1, array, j, k - j); + array[k] = value; + } + } + } + + public static GENERIC_BRACES void quickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { + quickSort(array, 0, array.length, comp); + } + + public static GENERIC_BRACES void quickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { + quickSort(array, 0, length, comp); + } + + public static GENERIC_BRACES void quickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { + int length = to - from; + if(length <= 0) return; + if(length < 16) { + selectionSort(array, from, to, comp); + return; + } + KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)]; + int a = from, b = a, c = to - 1, d = c; + for(int compare;;swap(array, b++, c--)) { + for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) { + if(compare == 0) swap(array, a++, b); + } + for(;b>=c && (compare = comp.compare(array[c], pivot)) >= 0;c--) { + if(compare == 0) swap(array, c, d--); + } + if(b>c) break; + } + swap(array, from, b, Math.min(a - from, b - a)); + swap(array, b, to, Math.min(d - c, to - d - 1)); + if((length = b - a) > 1) quickSort(array, from, from + length, comp); + if((length = d - c) > 1) quickSort(array, to - length, to, comp); + } + + public static COMPAREABLE_BRACES void quickSort(KEY_TYPE[] array) { + quickSort(array, 0, array.length); + } + + public static COMPAREABLE_BRACES void quickSort(KEY_TYPE[] array, int length) { + quickSort(array, 0, length); + } + + public static COMPAREABLE_BRACES void quickSort(KEY_TYPE[] array, int from, int to) { + int length = to - from; + if(length <= 0) return; + if(length < 16) { + selectionSort(array, from, to); + return; + } + KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8) : medium(array, from, from + (length / 2), to - 1)]; + int a = from, b = a, c = to - 1, d = c; + for(int comp = 0;;swap(array, b++, c--)) { + for(;b<=c && (comp = COMPARE_TO(array[b], pivot)) <= 0;b++) { + if(comp == 0) swap(array, a++, b); + } + for(;b>=c && (comp = COMPARE_TO(array[c], pivot)) >= 0;c--) { + if(comp == 0) swap(array, c, d--); + } + if(b>c) break; + } + swap(array, from, b, Math.min(a - from, b - a)); + swap(array, b, to, Math.min(d - c, to - d - 1)); + if((length = b - a) > 1) quickSort(array, from, from + length); + if((length = d - c) > 1) quickSort(array, to - length, to); + } + + public static GENERIC_BRACES void swap(KEY_TYPE[] a, int from, int to) { + KEY_TYPE t = a[from]; + a[from] = a[to]; + a[to] = t; + } + + static GENERIC_BRACES void swap(KEY_TYPE[] a, int from, int to, int length) { + to -= length; + for(int i = 0;i 0 ? b : comp.compare(data[a], data[c]) > 0 ? c : a); + } + + static COMPAREABLE_BRACES int subMedium(KEY_TYPE[] data, int a, int b, int c, int length) { + return medium(data, medium(data, a, a + length, a + (length * 2)), medium(data, b - length, b, b + length), medium(data, c - (length * 2), c - length, c)); + } + + static COMPAREABLE_BRACES int medium(KEY_TYPE[] data, int a, int b, int c) { + return COMPARE_TO(data[a], data[b]) < 0 ? (COMPARE_TO(data[b], data[c]) < 0 ? b : COMPARE_TO(data[a], data[c]) < 0 ? c : a) : (COMPARE_TO(data[b], data[c]) > 0 ? b : COMPARE_TO(data[a], data[c]) > 0 ? c : a); + } + + static class QuickSortAction KEY_COMPAREABLE_TYPE extends RecursiveAction { + private static final long serialVersionUID = 0L; + KEY_TYPE[] array; + int from; + int to; + + QuickSortAction(KEY_TYPE[] array, int from, int to) + { + this.array = array; + this.from = from; + this.to = to; + } + + @Override + protected void compute() + { + int length = to - from; + if(length <= 0) return; + if(length < 16) { + selectionSort(array, from, to); + return; + } + KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8) : medium(array, from, from + (length / 2), to - 1)]; + int a = from, b = a, c = to - 1, d = c; + for(int comp = 0;;swap(array, b++, c--)) { + for(;b<=c && (comp = COMPARE_TO(array[b], pivot)) <= 0;b++) { + if(comp == 0) swap(array, a++, b); + } + for(;b>=c && (comp = COMPARE_TO(array[c], pivot)) >= 0;c--) { + if(comp == 0) swap(array, c, d--); + } + if(b>c) break; + } + swap(array, from, b, Math.min(a - from, b - a)); + swap(array, b, to, Math.min(d - c, to - d - 1)); + if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionBRACES(array, from, from + (b - a)), new QuickSortActionBRACES(array, to - (d - c), to)); + else if(b - a > 1) new QuickSortActionBRACES(array, from, from + (b - a)).invoke(); + else if(d - c > 1) new QuickSortActionBRACES(array, to - (d - c), to).invoke(); + } + } + + static class QuickSortActionComp KEY_GENERIC_TYPE extends RecursiveAction { + private static final long serialVersionUID = 0L; + KEY_TYPE[] array; + int from; + int to; + COMPARATOR KEY_GENERIC_TYPE comp; + + QuickSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) + { + this.array = array; + this.from = from; + this.to = to; + this.comp = comp; + } + + @Override + protected void compute() + { + int length = to - from; + if(length <= 0) return; + if(length < 16) { + selectionSort(array, from, to, comp); + return; + } + KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)]; + int a = from, b = a, c = to - 1, d = c; + for(int compare;;swap(array, b++, c--)) { + for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) { + if(compare == 0) swap(array, a++, b); + } + for(;b>=c && (compare = comp.compare(array[c], pivot)) >= 0;c--) { + if(compare == 0) swap(array, c, d--); + } + if(b>c) break; + } + swap(array, from, b, Math.min(a - from, b - a)); + swap(array, b, to, Math.min(d - c, to - d - 1)); + if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompBRACES(array, from, from + (b - a), comp), new QuickSortActionCompBRACES(array, to - (d - c), to, comp)); + else if(b - a > 1) new QuickSortActionCompBRACES(array, from, from + (b - a), comp).invoke(); + else if(d - c > 1) new QuickSortActionCompBRACES(array, to - (d - c), to, comp).invoke(); + } + } } \ No newline at end of file