#include <iostream>
using namespace std;
template <typename T>
void sink(T arr[], int pos, int N, int d) {
int start(pos*d + 1), max_index(start);
while(start < N) {
// Find the max amongst direct "children" of position `pos`
for(int i = start + 1; (i < start + d) && (i < N); i++) {
if (arr[i] > arr[max_index]) {
max_index = i;
}
}
// If arr[pos] is less than the max we found, switch them and proceed
if (arr[pos] < arr[max_index]) {
// Switch arr[pos] and arr[max_index] to enforce heap condition
T tmp = arr[pos];
arr[pos] = arr[max_index];
arr[max_index] = tmp;
// Update pos and start to sink "recursively"
pos = max_index;
start = pos*d + 1;
max_index = start;
} else { // Else, there is nothing to worry about further ...
break;
}
}
}
template <typename T>
void dheapsort(T arr[], int N, int d) {
// The for loop "heapify" the array.
for (int k = N/d; k >= 0; k--) {
sink<T>(arr, k, N, d);
}
// We exchange the max (located at arr[0] since the array became a heap)
// with the last element.
// Then we enforce the heap condition on the N-1 remaining elements.
// N is then decreased
// (...) so on.
while (N > 1) {
T tmp = arr[N-1];
arr[N-1] = arr[0];
arr[0] = tmp;
sink<T>(arr, 0, --N, d);
}
}
// Then you just have to use it with the parameters you want ...
// An example :
int main() {
int test[10] = {1, 3, 2, 5, 6, 8, 2, 8, 10, 11};
dheapsort(test, 10, 3);
for (int i = 0; i < 10; i++)
cout << "test[" << i << "] : " << test[i] << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnZvaWQgc2luayhUIGFycltdLCBpbnQgcG9zLCBpbnQgTiwgaW50IGQpIHsKICAgIGludCBzdGFydChwb3MqZCArIDEpLCBtYXhfaW5kZXgoc3RhcnQpOwogICAgd2hpbGUoc3RhcnQgPCBOKSB7CiAgICAgICAgLy8gRmluZCB0aGUgbWF4IGFtb25nc3QgZGlyZWN0ICJjaGlsZHJlbiIgb2YgcG9zaXRpb24gYHBvc2AKICAgICAgICBmb3IoaW50IGkgPSBzdGFydCArIDE7IChpIDwgc3RhcnQgKyBkKSAmJiAoaSA8IE4pOyBpKyspIHsKICAgICAgICAgICAgaWYgKGFycltpXSA+IGFyclttYXhfaW5kZXhdKSB7CiAgICAgICAgICAgICAgICBtYXhfaW5kZXggPSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIElmIGFycltwb3NdIGlzIGxlc3MgdGhhbiB0aGUgbWF4IHdlIGZvdW5kLCBzd2l0Y2ggdGhlbSBhbmQgcHJvY2VlZAogICAgICAgIGlmIChhcnJbcG9zXSA8IGFyclttYXhfaW5kZXhdKSB7CiAgICAgICAgICAgIC8vIFN3aXRjaCBhcnJbcG9zXSBhbmQgYXJyW21heF9pbmRleF0gdG8gZW5mb3JjZSBoZWFwIGNvbmRpdGlvbgogICAgICAgICAgICBUIHRtcCA9IGFycltwb3NdOwogICAgICAgICAgICBhcnJbcG9zXSA9IGFyclttYXhfaW5kZXhdOwogICAgICAgICAgICBhcnJbbWF4X2luZGV4XSA9IHRtcDsKICAgICAgICAgICAgLy8gVXBkYXRlIHBvcyBhbmQgc3RhcnQgdG8gc2luayAicmVjdXJzaXZlbHkiCiAgICAgICAgICAgIHBvcyA9IG1heF9pbmRleDsKICAgICAgICAgICAgc3RhcnQgPSBwb3MqZCArIDE7CiAgICAgICAgICAgIG1heF9pbmRleCA9IHN0YXJ0OwogICAgICAgIH0gZWxzZSB7IC8vIEVsc2UsIHRoZXJlIGlzIG5vdGhpbmcgdG8gd29ycnkgYWJvdXQgZnVydGhlciAuLi4KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kdm9pZCBkaGVhcHNvcnQoVCBhcnJbXSwgaW50IE4sIGludCBkKSB7CiAgICAvLyBUaGUgZm9yIGxvb3AgImhlYXBpZnkiIHRoZSBhcnJheS4KICAgIGZvciAoaW50IGsgPSBOL2Q7IGsgPj0gMDsgay0tKSB7CiAgICAgICAgc2luazxUPihhcnIsIGssIE4sIGQpOwogICAgfQogICAgLy8gV2UgZXhjaGFuZ2UgdGhlIG1heCAobG9jYXRlZCBhdCBhcnJbMF0gc2luY2UgdGhlIGFycmF5IGJlY2FtZSBhIGhlYXApCiAgICAvLyB3aXRoIHRoZSBsYXN0IGVsZW1lbnQuCiAgICAvLyBUaGVuIHdlIGVuZm9yY2UgdGhlIGhlYXAgY29uZGl0aW9uIG9uIHRoZSBOLTEgcmVtYWluaW5nIGVsZW1lbnRzLgogICAgLy8gTiBpcyB0aGVuIGRlY3JlYXNlZAogICAgLy8gKC4uLikgc28gb24uCiAgICB3aGlsZSAoTiA+IDEpIHsKICAgICAgICBUIHRtcCA9IGFycltOLTFdOwogICAgICAgIGFycltOLTFdID0gYXJyWzBdOwogICAgICAgIGFyclswXSA9IHRtcDsKICAgICAgICBzaW5rPFQ+KGFyciwgMCwgLS1OLCBkKTsKICAgIH0KfQoKLy8gVGhlbiB5b3UganVzdCBoYXZlIHRvIHVzZSBpdCB3aXRoIHRoZSBwYXJhbWV0ZXJzIHlvdSB3YW50IC4uLgovLyBBbiBleGFtcGxlIDoKCmludCBtYWluKCkgewogICAgaW50IHRlc3RbMTBdID0gezEsIDMsIDIsIDUsIDYsIDgsIDIsIDgsIDEwLCAxMX07CiAgICBkaGVhcHNvcnQodGVzdCwgMTAsIDMpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKQogICAgICAgIGNvdXQgPDwgInRlc3RbIiA8PCBpIDw8ICJdIDogIiA8PCB0ZXN0W2ldIDw8IGVuZGw7CiAgICByZXR1cm4gMDsKfQ==