static void MergeSort(IMemoryAcessor ma, long start, long end, long subSortSize, IMASort subSort, CancellationToken token) { IMemoryAcessor aux = ma.CloneAUX(); for (long startInner = start; startInner < end; startInner += subSortSize) { long endInner = startInner + subSortSize; if (endInner > end) { endInner = end; } subSort.Sort(ma, end - endInner, end - startInner, token); } for (long size = subSortSize; size < end - start; size <<= 1) { for (long startInner = start; startInner < end; startInner += (size << 1)) { long midInner = startInner + size; long endInner = midInner + size; if (midInner < end) { if (endInner > end) { endInner = end; } Merge(aux, ma, end - endInner, end - midInner, end - startInner, token); } } } }
static void SinkDown(IMemoryAcessor ma, long root, long start, long end, CancellationToken token) { long size = end - start; while (true) { long maxIndex = root; long leftIndex = (root << 1) + 1; long rightIndex = leftIndex + 1; if (leftIndex < size) { if (ma.Read(start + maxIndex) < ma.Read(start + leftIndex)) { maxIndex = leftIndex; } if (rightIndex < size && ma.Read(start + maxIndex) < ma.Read(start + rightIndex)) { maxIndex = rightIndex; } } if (maxIndex == root) { break; } ma.Swap(start + maxIndex, start + root, token); root = maxIndex; } }
static public void Copy(IMemoryAcessor source, long sourceIndex, IMemoryAcessor destination, long destinationIndex, long length, CancellationToken token) { for (long index = 0; index < length; ++index) { token.ThrowIfCancellationRequested(); destination.Write(destinationIndex + index, source.Read(sourceIndex + index)); } }
static void HeapSort(IMemoryAcessor ma, long start, long end, CancellationToken token) { Heapify(ma, start, end, token); for (long size = end - start; size > 0; --size) { SinkDown(ma, 0, start, start + size, token); ma.Swap(start, start + size - 1, token); } }
static void Heapify(IMemoryAcessor ma, long start, long end, CancellationToken token) { if (end - start < 2) { return; } long root = ((end - start) >> 1) - 1; while (true) { SinkDown(ma, root, start, end, token); if (root == 0) { break; } --root; } }
static void Merge(IMemoryAcessor aux, IMemoryAcessor ma, long start, long mid, long end, CancellationToken token) { Utils.Copy(ma, start, aux, start, mid - start, token); long left = start; long right = mid; long index = start; while (left < mid && right < end) { token.ThrowIfCancellationRequested(); if (aux.Read(left) < ma.Read(right)) { ma.Write(index++, aux.Read(left++)); } else { ma.Write(index++, ma.Read(right++)); } } Utils.Copy(aux, left, ma, index, mid - left, token); }
static void QuickSort(IMemoryAcessor ma, long start, long end, CancellationToken token) { if (end - start <= 1) { return; } Stack <(long, long)> stack = new Stack <(long, long)>(); stack.Push((start, end)); while (stack.Count > 0) { (long startInner, long endInner) = stack.Pop(); long p = PartArray(ma, startInner, endInner - 1, token); if (p - startInner < endInner - p - 1) { if (p + 2 < endInner) { stack.Push((p + 1, endInner)); } if (startInner + 1 < p) { stack.Push((startInner, p)); } } else { if (startInner + 1 < p) { stack.Push((startInner, p)); } if (p + 2 < endInner) { stack.Push((p + 1, endInner)); } } } }
static long PartArray(IMemoryAcessor ma, long leftIndex, long rightIndex, CancellationToken token) { long pivotIndex = leftIndex + ((rightIndex - leftIndex + 1) >> 1); ma.Swap(leftIndex, pivotIndex, token); UInt16 pivot = ma.Read(leftIndex); long left = leftIndex; long right = rightIndex + 1; while (true) { while (ma.Read(++left) < pivot) { if (left == rightIndex) { break; } } while (ma.Read(--right) > pivot) { if (right == leftIndex) { break; } } if (left >= right) { break; } ma.Swap(left, right, token); } ma.Swap(leftIndex, right, token); return(right); }
public void Sort(IMemoryAcessor ma, long start, long end, CancellationToken token) { QuickSort(ma, start, end, token); }
public void Sort(IMemoryAcessor ma, long start, long end, CancellationToken token) { MergeSort(ma, start, end, subSortSize, subSort, token); }