private static void HeapSort(CodeContext /*!*/ context, PythonList list, bool reverse) { // for an ascending sort (reverse = false), use a max-heap, and vice-versa if (reverse) { DoHeapify(context, list); } else { DoHeapifyMax(context, list); } int last = list._size - 1; while (last > 0) { // put the root node (max if ascending, min if descending) at the end list.FastSwap(0, last); // shrink heap by 1 last--; // maintain heap invariant if (reverse) { SiftDown(context, list, 0, last); } else { SiftDownMax(context, list, 0, last); } } }
public static object heappop(CodeContext /*!*/ context, PythonList list) { lock (list) { int last = list._size - 1; if (last < 0) { throw PythonOps.IndexError("index out of range"); } list.FastSwap(0, last); list._size--; SiftDown(context, list, 0, last - 1); return(list._data[list._size]); } }
private static void SiftUpMax(CodeContext /*!*/ context, PythonList heap, int index) { while (index > 0) { int parent = (index - 1) / 2; if (IsLessThan(context, heap._data[parent], heap._data[index])) { heap.FastSwap(parent, index); index = parent; } else { return; } } }
private static void SiftDownMax(CodeContext /*!*/ context, PythonList heap, int start, int stop) { int parent = start; int child; while ((child = parent * 2 + 1) <= stop) { // find the larger sibling if (child + 1 <= stop && IsLessThan(context, heap._data[child], heap._data[child + 1])) { child++; } // check if max-heap property is violated if (IsLessThan(context, heap._data[parent], heap._data[child])) { heap.FastSwap(parent, child); parent = child; } else { return; } } }