home *** CD-ROM | disk | FTP | other *** search
- ------------------------------------------------------------------------------
- -- --
- -- GNAT RUNTIME COMPONENTS --
- -- --
- -- G N A T . H E A P _ S O R T _ A --
- -- --
- -- B o d y --
- -- --
- -- $Revision: 1.3 $ --
- -- --
- -- Copyright (c) 1994 NYU, All Rights Reserved --
- -- --
- -- The GNAT library is free software; you can redistribute it and/or modify --
- -- it under terms of the GNU Library General Public License as published by --
- -- the Free Software Foundation; either version 2, or (at your option) any --
- -- later version. The GNAT library is distributed in the hope that it will --
- -- be useful, but WITHOUT ANY WARRANTY; without even the implied warranty --
- -- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --
- -- Library General Public License for more details. You should have --
- -- received a copy of the GNU Library General Public License along with --
- -- the GNAT library; see the file COPYING.LIB. If not, write to the Free --
- -- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
- -- --
- ------------------------------------------------------------------------------
-
- package body GNAT.Heap_Sort_A is
-
- ----------
- -- Sort --
- ----------
-
- -- We are using the classical heapsort algorithm (i.e. Floyd's Treesort3)
- -- as described by Knuth (ref???) with the modification that is mentioned
- -- in excercise ???. For more details on this algorithm, see Robert B. K.
- -- Dewar PhD thesis "The use of Computers in the X-ray Phase Problem".
- -- University of Chicago, 1968.
-
- procedure Sort (N : Positive; Move : Move_Procedure; Lt : Lt_Function) is
-
- Max : Positive := N;
- -- Current Max index in tree being sifted
-
- procedure Sift (S : Positive);
- -- This procedure sifts up node S, i.e. converts the subtree rooted
- -- at node S into a heap, given the precondition that any sons of
- -- S are already heaps. On entry, the contents of node S is found
- -- in the temporary (index 0), the actual contents of node S on
- -- entry are irrelevant. This is just a minor optimization to avoid
- -- what would otherwise be two junk moves in phase two of the sort.
-
- procedure Sift (S : Positive) is
- C : Positive := S;
- Son : Positive;
- Father : Positive;
-
- begin
- -- This is where the optimization is done, normally we would do a
- -- comparison at each stage between the current node and the larger
- -- of the two sons, and continue the sift only if the current node
- -- was less than this maximum. In this modified optimized version,
- -- we assume that the current node will be less than the larger
- -- son, and unconditionally sift up. Then when we get to the bottom
- -- of the tree, we check parents to make sure that we did not make
- -- a mistake. This roughly cuts the number of comparisions in half,
- -- since it is almost always the case that our assumption is correct.
-
- -- Loop to pull up larger sons
-
- loop
- Son := 2 * C;
- exit when Son > Max;
-
- if Son < Max and then Lt (Son, Son + 1) then
- Son := Son + 1;
- end if;
-
- Move (Son, C);
- C := Son;
- end loop;
-
- -- Loop to check fathers
-
- while C /= S loop
- Father := C / 2;
-
- if Lt (Father, 0) then
- Move (Father, C);
- C := Father;
- else
- exit;
- end if;
- end loop;
-
- -- Last step is to pop the sifted node into place
-
- Move (0, C);
- end Sift;
-
- -- Start of processing for Sort
-
- begin
- -- Phase one of heapsort is to build the heap. This is done by
- -- sifting nodes N/2 .. 1 in sequence.
-
- for J in reverse 1 .. N / 2 loop
- Move (J, 0);
- Sift (J);
- end loop;
-
- -- In phase 2, we sift node 1 repeatedly, so that it is the largest
- -- node in the remaining heap, and then exchange it with the last node.
-
- while Max > 1 loop
- Sift (1);
- Move (Max, 0);
- Move (1, Max);
- Max := Max - 1;
- end loop;
-
- end Sort;
-
- end GNAT.Heap_Sort_A;
-