147 lines
4.4 KiB
C#
147 lines
4.4 KiB
C#
|
namespace Nerfed.Runtime;
|
|||
|
|
|||
|
public static class SpanExtensions
|
|||
|
{
|
|||
|
public static void QuickSort<T>(this Span<T> span, Comparison<T> comparison) {
|
|||
|
QuickSort(span, 0, span.Length - 1, comparison);
|
|||
|
}
|
|||
|
|
|||
|
private static void QuickSort<T>(this Span<T> span, int leftIndex, int rightIndex, Comparison<T> 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<T>(this Span<T> span, Comparison<T> 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<T>(Span<T> span, int size, int index, Comparison<T> 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<T>(this Span<T> span, T[] leftArray, T[] rightArray, Comparison<T> comparison) {
|
|||
|
MergeSort(span, leftArray, rightArray, 0, span.Length - 1, comparison);
|
|||
|
}
|
|||
|
|
|||
|
private static void MergeSort<T>(this Span<T> span, T[] leftArray, T[] rightArray, int left, int right, Comparison<T> 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<T>(Span<T> span, T[] leftArray, T[] rightArray, int left, int middle, int right, Comparison<T> 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<T>(this Span<T> span, Comparison<T> 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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|