public bool SequenceEqual(ChunkedArray <T> other) { bool result = true; if (_length != other._length) { return(false); } var i = 0; for (; i < _rows - 1; ++i) { result = _buffer[i].SequenceEqual(other._buffer[i]); if (!result) { return(result); } } for (var t = 0; t < _lastArraySize; ++t) { if (_buffer[i][t].CompareTo(other._buffer[i][t]) != 0) { return(false); } } return(result); }
internal static void IntrospectiveSort(ChunkedArray <T> keys, int left, int length, IComparer <T> comparer) { if (length < 2) { return; } IntroSort(keys, left, length + left - 1, 2 * IntrospectiveSortUtilities.FloorLog2(keys.Length), comparer); }
private static void Swap(ChunkedArray <T> a, int i, int j) { if (i != j) { T t = a[i]; a[i] = a[j]; a[j] = t; } }
private static void SwapIfGreater(ChunkedArray <T> keys, IComparer <T> comparer, int a, int b) { if (a != b) { if (comparer.Compare(keys[a], keys[b]) > 0) { T key = keys[a]; keys[a] = keys[b]; keys[b] = key; } } }
public void CopyFrom(ChunkedArray <T> source, int validIndex) { SetSize(validIndex); var i = 0; for (; i < _rows - 1; ++i) { Array.Copy(source._buffer[i], _buffer[i], _maxWidth); } Array.Copy(source._buffer[i], _buffer[i], _lastArraySize); }
// TODO : increase speed public static ChunkedArray <T> CreateFromArray(T[] source) { ChunkedArray <T> result = new ChunkedArray <T>(source.Length); var i = 0; foreach (var t in source) { result[i++] = t; } return(result); }
private static void Heapsort(ChunkedArray <T> keys, int lo, int hi, IComparer <T> comparer) { int n = hi - lo + 1; for (int i = n / 2; i >= 1; i = i - 1) { DownHeap(keys, i, n, lo, comparer); } for (int i = n; i > 1; i = i - 1) { Swap(keys, lo, lo + i - 1); DownHeap(keys, 1, i - 1, lo, comparer); } }
private static void InsertionSort(ChunkedArray <T> keys, int lo, int hi, IComparer <T> comparer) { int i, j; T t; for (i = lo; i < hi; i++) { j = i; t = keys[i + 1]; while (j >= lo && comparer.Compare(t, keys[j]) < 0) { keys[j + 1] = keys[j]; j--; } keys[j + 1] = t; } }
private static void IntroSort(ChunkedArray <T> keys, int lo, int hi, int depthLimit, IComparer <T> comparer) { while (hi > lo) { int partitionSize = hi - lo + 1; if (partitionSize <= IntrospectiveSortUtilities.IntrosortSizeThreshold) { if (partitionSize == 1) { return; } if (partitionSize == 2) { SwapIfGreater(keys, comparer, lo, hi); return; } if (partitionSize == 3) { SwapIfGreater(keys, comparer, lo, hi - 1); SwapIfGreater(keys, comparer, lo, hi); SwapIfGreater(keys, comparer, hi - 1, hi); return; } InsertionSort(keys, lo, hi, comparer); return; } if (depthLimit == 0) { Heapsort(keys, lo, hi, comparer); return; } depthLimit--; int p = PickPivotAndPartition(keys, lo, hi, comparer); // Note we've already partitioned around the pivot and do not have to move the pivot again. IntroSort(keys, p + 1, hi, depthLimit, comparer); hi = p - 1; } }
private static void DownHeap(ChunkedArray <T> keys, int i, int n, int lo, IComparer <T> comparer) { T d = keys[lo + i - 1]; int child; while (i <= n / 2) { child = 2 * i; if (child < n && comparer.Compare(keys[lo + child - 1], keys[lo + child]) < 0) { child++; } if (!(comparer.Compare(d, keys[lo + child - 1]) < 0)) { break; } keys[lo + i - 1] = keys[lo + child - 1]; i = child; } keys[lo + i - 1] = d; }
private static int PickPivotAndPartition(ChunkedArray <T> keys, int lo, int hi, IComparer <T> comparer) { // Compute median-of-three. But also partition them, since we've done the comparison. int middle = lo + ((hi - lo) / 2); // Sort lo, mid and hi appropriately, then pick mid as the pivot. SwapIfGreater(keys, comparer, lo, middle); // swap the low with the mid point SwapIfGreater(keys, comparer, lo, hi); // swap the low with the high SwapIfGreater(keys, comparer, middle, hi); // swap the middle with the high T pivot = keys[middle]; Swap(keys, middle, hi - 1); int left = lo, right = hi - 1; // We already partitioned lo and hi and put the pivot in hi - 1. And we pre-increment & decrement below. while (left < right) { while (comparer.Compare(keys[++left], pivot) < 0) { ; } while (comparer.Compare(pivot, keys[--right]) < 0) { ; } if (left >= right) { break; } Swap(keys, left, right); } // Put pivot in the right location. Swap(keys, left, (hi - 1)); return(left); }
public static void Sort(ChunkedArray <T> keys, int index, int length, IComparer <T> comparer) { IntrospectiveSort(keys, index, length, comparer); }