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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
-------------------------------------------------------------------------------
--
-- <STRONG>Copyright (c) 1999 - 2002 by Thomas Wolf.</STRONG>
-- <BLOCKQUOTE>
-- AdaBrowse is free software; you can redistribute it and/or modify it
-- under the terms of the GNU General Public License as published by the
-- Free Software Foundation; either version 2, or (at your option) any
-- later version. AdaBrowse is distributed in the hope that it will be
-- useful, but <EM>without any warranty</EM>; without even the implied
-- warranty of <EM>merchantability or fitness for a particular purpose.</EM>
-- See the GNU General Public License for more details. You should have
-- received a copy of the GNU General Public License with this distribution,
-- see file "<A HREF="GPL.txt">GPL.txt</A>". If not, write to the Free
-- Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-- USA.
-- </BLOCKQUOTE>
-- <BLOCKQUOTE>
-- As a special exception from the GPL, if other files instantiate generics
-- from this unit, or you link this unit with other files to produce an
-- executable, this unit does not by itself cause the resulting executable
-- to be covered by the GPL. This exception does not however invalidate any
-- other reasons why the executable file might be covered by the GPL.
-- </BLOCKQUOTE>
--
-- <DL><DT><STRONG>
-- Author:</STRONG><DD>
-- Thomas Wolf (TW)
-- <ADDRESS><A HREF="mailto:twolf@acm.org">twolf@acm.org</A></ADDRESS></DL>
--
-- <DL><DT><STRONG>
-- Purpose:</STRONG><DD>
-- Speed and space optimized quicksort. Actually, an <EM>introspective
-- quicksort</EM> with a <STRONG>worst-case</STRONG> runtime complexity of
-- <CODE>O (N * log2 (N))</CODE>.</DL>
--
-- <DL><DT><STRONG>
-- Literature:</STRONG><DD>
-- Musser, D.R.: "Introspective Sorting and Selection Algorithms",
-- <EM>Software -- Practice & Experience (8):983-993</EM>; 1997.</DL>
--
-- <DL><DT><STRONG>
-- Tasking semantics:</STRONG><DD>
-- N/A. Not abortion-safe.</DL>
--
-- <DL><DT><STRONG>
-- Storage semantics:</STRONG><DD>
-- No dynamic storage allocation. Stack space used is
-- <CODE>O (log2 (N))</CODE>.</DL>
--
-- <!--
-- Revision History
--
-- 21-JAN-1999 TW Initial version as package TW_Sorting.
-- 26-NOV-2001 TW Changed into GAL.Sorting, added 'Sort_Slice_G'.
-- -->
-------------------------------------------------------------------------------
pragma License (Modified_GPL);
package GAL.Sorting is
pragma Elaborate_Body;
----------------------------------------------------------------------------
-- A sort with a classic interface:
generic
type Index_Type is (<>);
type Element_Type is private;
type Array_Type is array (Index_Type range <>) of Element_Type;
with function "<" (Left, Right : in Element_Type) return Boolean is <>;
procedure Sort_G
(To_Sort : in out Array_Type);
-- Sorts the array into ascending order according to the given function
-- "<". This is an introspective quicksort with average *and* worst-case
-- performance complexity of O(log2(N)). Stack space usage is bounded by
-- log2(N).
-- If To_Sort'Length >= System.Max_Int, Constraint_Error may be raised.
-- (I didn't test that!) However, System.Max_Int is typically >= 2**31-1,
-- and sorting arrays of 2 Gigabytes or more is not exactly a common case.
----------------------------------------------------------------------------
-- The same with an access parameter and range bounds.
generic
type Index_Type is (<>);
type Element_Type is private;
type Array_Type is array (Index_Type range <>) of Element_Type;
with function "<" (Left, Right : in Element_Type) return Boolean is <>;
procedure Sort_Slice_G
(To_Sort : access Array_Type;
From, To : in Index_Type);
-- A no-op if To_Sort'Length <= 1 or To < From. In both cases, it is
-- irrelevant whether or not 'To' and 'From' are within To_Sort'Range.
-- If both To_Sort'Length > 1 and From <= To, a check is made to ensure
-- that both 'From' and 'To' are within To_Sort'Range, and Constraint_Error
-- will be raised without modifying the array if not. Otherwise, the given
-- slice To_Sort (From .. To) is sorted into ascending order according to
-- '<'.
----------------------------------------------------------------------------
-- A very general sort that can be used to sort whatever you like. As
-- long as you can provide random access in constant time, this will
-- be a logarithmic sort. (It's an introspective quicksort, too.)
generic
with function Is_Smaller (Left, Right : in Integer) return Boolean;
-- Shall return True if the element at index 'Left' is smaller than
-- the element at index 'Right' and Fasle otherwise.
with procedure Copy (To, From : in Integer);
-- Shall copy the element at index 'From' to position 'To'.
procedure Sort_Indexed_G
(Left, Right : in Natural);
-- Sorts range Left .. Right of your data by calling 'Is_Smaller' for
-- comparisons and 'Move' to move elements around. Both 'Is_Smaller'
-- and 'Move' must be prepared to receive indices -1 and -2, which denote
-- two single (and different) temporary locations. Both routines are never
-- called with both indices negative, one index at least is always
-- in the (Left .. Right).
----------------------------------------------------------------------------
-- Same as above, but using access-to-subroutines.
type Comparator is access
function (Left, Right : in Integer) return Boolean;
type Copier is access
procedure (To, From : in Integer);
procedure Sort
(Left, Right : in Natural;
Is_Smaller : in Comparator;
Copy : in Copier);
-- Of course, both 'Is_Smaller' and 'Copy' must not be null or this will
-- raise Constraint_Error!
----------------------------------------------------------------------------
end GAL.Sorting;
|