1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
void heap_from_root(MVector &v, int i, int n) {
int end=n,j=0;
// Identify the lowest root and how many sons it has. If it only has one son, set j=1.
if (n==1) { n = 0; j = 1; }
else if ((n-2) % 2 == 0) { n = (n-2)/2; }
else if ((n-1) % 2 == 0) { n = (n-1)/2; j=1; }
while (i <= n) { // Start from the lowest root, and go up until the highest root.
if (j==0) { // If 2 sons, then check for the biggest value. If the biggest value is greater than root, exchange.
if (v[2*n+1] > v[2*n+2] && v[2*n+1] > v[n]) { v.swap(2*n+1,n); }
if (v[2*n+2] > v[2*n+1] && v[2*n+2] > v[n]) { v.swap(2*n+2,n); }
}
if (j==1) { // If 1 son, if the son's value is greater than the root, exchange.
if (v[2*n+1] > v[n]) { v.swap(2*n+1,n); }
j=0; // As only the last root can only have one son, set j to 0.
}
n--; // Go backwards to the next root.
}
/* The top value of the heap will now be the biggest value. If the heap hasn't been completed sorted,
put the biggest value at the END of the heap, and restart the algorithm, this time excluding that last
value. Repeating this recursively will mean the heap will be sorted in ascending order. This saves using
significant excess memory. */
if (i < end) { v.swap(i,end); end--; heap_from_root(v,i,end); }
}
void heap(MVector &v) { heap_from_root(v,0,v.size()-1); }
|