namespace Nerfed.Runtime; public static class SpanExtensions { public static void QuickSort(this Span span, Comparison comparison) { QuickSort(span, 0, span.Length - 1, comparison); } private static void QuickSort(this Span span, int leftIndex, int rightIndex, Comparison comparison) { for(;;) { int i = leftIndex; int j = rightIndex; T pivot = span[leftIndex]; while(i <= j) { while(comparison(span[i], pivot) < 0) { i++; } while(comparison(span[j], pivot) > 0) { j--; } if(i <= j) { (span[i], span[j]) = (span[j], span[i]); i++; j--; } } if(leftIndex < j) { QuickSort(span, leftIndex, j, comparison); } if(i < rightIndex) { leftIndex = i; continue; } break; } } public static void HeapSort(this Span span, Comparison comparison) { if(span.Length <= 1) { return; } for(int i = span.Length / 2 - 1; i >= 0; i--) { Heapify(span, span.Length, i, comparison); } for(int i = span.Length - 1; i >= 0; i--) { (span[0], span[i]) = (span[i], span[0]); Heapify(span, i, 0, comparison); } } private static void Heapify(Span span, int size, int index, Comparison comparison) { for(;;) { int largestIndex = index; int leftChild = 2 * index + 1; int rightChild = 2 * index + 2; if(leftChild < size && comparison(span[leftChild], span[largestIndex]) > 0) { largestIndex = leftChild; } if(rightChild < size && comparison(span[rightChild], span[largestIndex]) > 0) { largestIndex = rightChild; } if(largestIndex != index) { (span[index], span[largestIndex]) = (span[largestIndex], span[index]); index = largestIndex; continue; } break; } } public static void MergeSort(this Span span, T[] leftArray, T[] rightArray, Comparison comparison) { MergeSort(span, leftArray, rightArray, 0, span.Length - 1, comparison); } private static void MergeSort(this Span span, T[] leftArray, T[] rightArray, int left, int right, Comparison comparison) { if(left < right) { int middle = left + (right - left) / 2; MergeSort(span, leftArray, rightArray, left, middle, comparison); MergeSort(span, leftArray, rightArray, middle + 1, right, comparison); MergeArray(span, leftArray, rightArray, left, middle, right, comparison); } } private static void MergeArray(Span span, T[] leftArray, T[] rightArray, int left, int middle, int right, Comparison comparison) { int leftArrayLength = middle - left + 1; int rightArrayLength = right - middle; int i, j; for(i = 0; i < leftArrayLength; ++i) { leftArray[i] = span[left + i]; } for(j = 0; j < rightArrayLength; ++j) { rightArray[j] = span[middle + 1 + j]; } i = 0; j = 0; int k = left; while(i < leftArrayLength && j < rightArrayLength) { if(comparison(leftArray[i], rightArray[j]) <= 0) { span[k++] = leftArray[i++]; } else { span[k++] = rightArray[j++]; } } while(i < leftArrayLength) { span[k++] = leftArray[i++]; } while(j < rightArrayLength) { span[k++] = rightArray[j++]; } } public static void InsertionSort(this Span span, Comparison comparison) { for(int i = 1; i < span.Length; i++) { T key = span[i]; int flag = 0; for(int j = i - 1; j >= 0 && flag != 1;) { if(comparison(key, span[j]) < 0) { span[j + 1] = span[j]; j--; span[j + 1] = key; } else { flag = 1; } } } } }