SOURCE FILE: heapsort.pas
(*************************************************************)
(*** HEAPSORT CODE ***)
(*************************************************************)
CONST
MaxElements = 1000; (* maximum number of elements in list *)
TYPE
ListElementType = Integer; (* simplified for discussion! *)
IndexType = 0 .. MaxElements;
ArrayType = ARRAY [1 .. MaxElements] OF ListElementType;
ListType = RECORD
Length : IndexType;
Info : ArrayType
END; (* ListType *)
(*************************************************************)
(* PROCEDURE SWAP *)
(*************************************************************)
PROCEDURE Swap
(VAR Element1, Element2 : ListElementType);
(* Swap the values of Element1 and Element 2. *)
VAR
Temp : ListElementType;
BEGIN (* Swap *)
Temp := Element1;
Element1 := Element2;
Element2 := Temp
END; (* Swap *)
(*************************************************************)
(* PROCEDURE HeapSort *)
(*************************************************************)
PROCEDURE HeapSort
(VAR List : ListType);
(* Sort the elements in List in ascending order, using *)
(* the HeapSort algorithm. *)
VAR
Index : IndexType;
(*************************************************************)
(* Nested PROCEDURE ReheapDown *)
(*************************************************************)
PROCEDURE ReheapDown
(VAR HeapElements : ArrayType;
Root : Integer;
Bottom : Integer);
VAR
HeapOK : Boolean;
MaxChild : Integer;
BEGIN (* ReheapDown *)
HeapOk := False;
(* while the current node has a left child *)
(* and we are not done re-heaping ... *)
WHILE (Root * 2 <= Bottom) AND NOT HeapOk DO
BEGIN
(* if the current node has no right child ... *)
IF Root * 2 = Bottom
THEN MaxChild := Root * 2
ELSE
IF HeapElements[Root * 2] > HeapElements[Root * 2 + 1]
THEN MaxChild := Root * 2
ELSE MaxChild := Root * 2 + 1;
(* If the current node has a key less than one *)
(* of the children, then pick the child with the *)
(* largest key, and swap keys with it *)
IF HeapElements[Root] < HeapElements[MaxChild]
THEN
BEGIN
Swap (HeapElements[Root], HeapElements[MaxChild]);
Root := MaxChild
END (* If not yet a heap *)
ELSE HeapOk := True
END; (* WHILE *)
END; (* ReheapDown *)
(***************************************************************)
(***************************************************************)
BEGIN (* HeapSort *)
WITH List DO
BEGIN
(* Build the original heap from the unsorted elements. *)
FOR Index := (Length DIV 2) DOWNTO 1 DO
ReheapDown (Info, Index, Length);
(* Sort the elements in the heap by swapping the root *)
(* (current largest) value with the last unsorted *)
(* value, then reheaping remaining part of the list. *)
(* Loop invariant: Info[1] .. Info[Index] represents *)
(* a heap AND Info[Index + 1] .. Info[Length] are *)
(* sorted in ascending order. *)
FOR Index := Length DOWNTO 2 DO
BEGIN
Swap (Info[1], Info[Index]);
ReheapDown (Info, 1, Index - 1)
END (* FOR loop *)
END (* WITH *)
END; (* HeapSort *)
(*************************************************************)
(*************************************************************)