void slide_down(const vertex &v, const T &value) { /* Jeżeli jesteśmy w liściu to nie ma gdzie zjeżdzać. */ if (lchild(v) > n) { array[v] = value; return; } /* Jeżeli wierzchołek ma jednego syna to sprawa dosyć prosta. */ if (lchild(v) == n) { if (value < array[lchild(v)]) { array[v] = value; } else { array[v] = array[lchild(v)]; array[lchild(v)] = value; } return; } /* Jeżeli ma obu synów to sprawdzamy czy mniejszy zaburzy porządek. */ vertex m = array[lchild(v)] < array[rchild(v)] ? lchild(v) : rchild(v); if (value > array[m]) { array[v] = array[m]; slide_down(m, value); } else { array[v] = value; } }
/* Remove number from heap Unspecified behavior if heap is empty */ int removeHeap(heap *aHeap) { assert(aHeap != NULL); assert(aHeap->size > 0); aHeap->size--; int retVal = aHeap->array[0]; aHeap->array[0] = aHeap->array[aHeap->size]; // Trickle down int position = 0; while (true) { int left = lchild(position); int right = rchild(position); int largest = position; if (left < aHeap->size && aHeap->array[left] > aHeap->array[largest]) { largest = left; } if (right < aHeap->size && aHeap->array[right] > aHeap->array[largest]) { largest = right; } if (largest == position) { break; } else { int tmp = aHeap->array[position]; aHeap->array[position] = aHeap->array[largest]; aHeap->array[largest] = tmp; position = largest; } } return retVal; }
/* 维持堆中以root为根的子堆的堆性质 */ static void heapify(int *heap, int root, int size, fun compare) { int left = lchild(root); int right = rchild(root); int most = root; /* 根、左子结点、右子结点中最大(大顶堆)或最小(小顶堆)的结点 */ if (left < size) /* 求出根、左子结点、右子结点中最大(大顶堆)或最小(小顶堆)的结点 */ most = !compare(heap[left], heap[most])? left: most; if (right < size) most = !compare(heap[right], heap[most])? right: most; if (most != root) { /* 最大/最小的结点应该在根上 */ swap(heap + most, heap + root); /* 若有变动,则应对most为根的子堆也进行堆性质维护 */ heapify(heap, most, size, compare); } }