Good day,
I am trying to implement the HeapSort Algorithm using WL. My attempt is shown below.
ClearAll[BubbleDown];
SetAttributes[BubbleDown, HoldFirst];
BubbleDown[H_, i_] := Module[{k, j, v, n = Length[H], heap},
k = i; v = H[[k]]; heap = False;
While[! heap && 2*k <= n,
j = 2*k;
If[j < n, If[H[[j]] < H[[j + 1]], j++]];
If[v >= H[[j]], heap = True, H[[k]] = H[[j]]; k = j];
];
H[[k]] = v]
ClearAll[HeapBottomUp];
SetAttributes[HeapBottomUp, HoldFirst];
HeapBottomUp[H_] := Module[{i, n = Length[H]},
For[i = Floor[n/2], i >= 1, i--,
BubbleDown[H, i]];
H
]
ClearAll[HeapSort];
SetAttributes[HeapSort, HoldFirst];
HeapSort[H_] := Module[{n = Length[H], T = H, i},
H = HeapBottomUp[H];
For[i = n, i >= 2, i--,
T[[i]] = H[[1]];
H[[{1, i}]] = H[[{i, 1}]];
H = H[[;; i - 1]];
BubbleDown[H, 1]
];
T
]
My main problem is that I do not want to use the local variable T
in the HeapSort
function. When I tried BubbleDown[H[[;;I-1]]
, it did not work because of the HoldFirst setting for the function.
Is there a way to address this in order to make my implementation in place (space complexity of O(1))?
Many thanks!
Hold*
attributes and operate on only a part of the object, functions such asHeapBottomUp
should accept an index argument and use that to determine where to operate. That way copies are avoided (and they would mess up the algorithm complexity). $\endgroup$