home *** CD-ROM | disk | FTP | other *** search
- Unit LGenHeap; {Generic Fully Dynamic Doubly-Linked Heap}
- {$R-,O+}
- {$B-}
- {*MUST* ensure Short-Circuit Boolean Evaluation!}
-
- {Introduces the Heap variant of the List Object}
-
- INTERFACE
-
- Uses GenList,NodeSort,DoubLink,FlexPntr;
-
-
- Type
- L_Heap = Object (List)
-
- Greater : NodeSortFunc;
-
- Procedure Init (SortBy : NodeSortFunc; Size : Word);
-
- { Size refers to ElementSize! }
-
- Procedure SiftDown (I,J : LongInt);
-
- { While I can think of No reason to }
- { Use SiftDown externally, there may }
- { be a reason, so I have exported it }
-
- Procedure SiftUp (Var Elem; Size : Word);
-
- { SiftUp can be used in place of Append }
- { In order to Create/Maintain a Heap as }
- { a Heap while adding elements, thus }
- { allowing the use of Sort instead of }
- { HeapSort which structures a Heap by }
- { using BuildHeap. }
-
- Procedure BuildHeap;
-
- { Creates the Heap structure from }
- { the ground up. }
-
- Procedure ChangeSort (NewSort : NodeSortFunc);
-
- { Permits redefinition of collating sequence }
- { for already established Heaps. }
-
- Procedure Sort;
-
- { Sorts a Heap into Ascending order }
- { Assumes HEAP is built or maintained. }
-
- Procedure HeapSort;
-
- { Sorts a Heap into Ascending order }
- { Assumes nothing about Heap structure. }
-
- Procedure Copy (H : L_Heap)
-
- End;
-
-
- IMPLEMENTATION
-
- Procedure Swap (Var D1,D2 : D_Node);
- {Performance Improvement: Swap Pointers -- Problems with Head and Tail
- and with referencing items
- to be swapped!}
- Var
- Temp : D_Node;
- Begin
- Temp.Create;
- Temp.Copy (D1);
- D1.Copy (D2);
- D2.Copy (Temp);
- Temp.Destroy
- End;
-
- Procedure L_Heap.Init (SortBy : NodeSortFunc; Size : Word);
- Begin
- List.Init (Size);
- Greater := SortBy
- End;
-
- Procedure L_Heap.SiftDown (I,J : LongInt);
- Var
- K : LongInt;
- Begin
- If I <= J Div 2 {J = "HeapLength"}
- Then
- Begin
- If (1+2*I) > J
- Then
- K := 2*I
- Else
- If Greater (Node_N(2*I)^,Node_N(1+2*I)^)
- Then
- K := 2*I
- Else
- K := 1+2*I;
- If Greater (Node_N(K)^,Node_N(I)^)
- Then
- Begin
- Swap (Node_N(K)^,Node_N(I)^);
- SiftDown (K,J)
- End
- End
- End;
-
- Procedure L_Heap.SiftUp (Var Elem; Size : Word);
- Var
- J,K : LongInt;
- Begin
- Append (Elem,Size);
- If CurrentLength >= 2 Then
- Begin
- K := CurrentLength;
- J := K Div 2;
- While ((J > 0) and (Greater (Node_N(K)^,Node_N(J)^))) do
- Begin
- Swap (Node_N(K)^,Node_N(J)^);
- K := J;
- J := K Div 2
- End
- End
- End;
-
- Procedure L_Heap.BuildHeap;
- Var
- I: LongInt;
- Begin
- For I := CurrentLength Div 2 DownTo 1 do SiftDown (I,CurrentLength)
- End;
-
- Procedure L_Heap.ChangeSort (NewSort : NodeSortFunc);
- Begin
- Greater := NewSort
- End;
-
- Procedure L_Heap.Sort; {Assumes HEAP is built or maintained}
- Var
- I : LongInt;
- Begin
- For I := CurrentLength DownTo 2 do
- Begin
- ReWind; { At least we CAN speed up access to Node 1! }
- Swap (Node_N(1)^,Node_N(I)^);
- SiftDown (1,I-1)
- End
- End;
-
- Procedure L_Heap.HeapSort;
- Var
- I : LongInt;
- Begin
- BuildHeap;
- Sort
- End;
-
- Procedure L_Heap.Copy (H : L_Heap);
- Begin
- Greater := H.Greater;
- List.Copy (H)
- End;
-
- BEGIN
- END.