home *** CD-ROM | disk | FTP | other *** search
- ASORTS
-
- General-purpose routines for sorting, searching and moving
- arrays of arbitrary elements.
-
- Copyright 1991, by J. W. Rider
-
-
- ASORTS provides the Turbo Pascal programmer with type
- definitions, functions and procedures to handle a variety of
- array sorting and searching tasks. Several of these are
- analogous to functions of the same name in the C programming
- language:
-
- qsort -- sort an array
-
- bsearch -- do a binary search of a sorted array for an
- element that satisfies some key
-
- lfind -- do a sequential ("linear") search of an unsorted
- (or sorted) array for an element that satisfies
- some key
-
- lsearch -- do a sequential search of an unsorted (or sorted)
- array for an element that satisfies some key. If
- the element is not found, then it is appended to
- the end of the array.
-
- (Non-C programmers: please note that "bsearch" and "lfind" do
- the equivalent task for sorted and unsorted arrays,
- respectively. It would make more sense to define "bfind" to
- search through a sorted array, and make "bsearch" insert a
- missing element into the array at the right location.
- However, these routines are provided for compatibility in
- converting C programs.)
-
- There are some routines that are provided for utility above and
- beyond what is available in standard C libraries:
-
- bfind -- do a binary search of a sorted array for an
- element that satisfies some key. (This differs
- from "bsearch" in that is "bfind" reports the
- "insertion index" if the key element is not
- found.)
-
- binsert -- do a binary search of a sorted array for an
- element that satisfies some key. If the element
- is not found, then the key element is inserted in
- the proper location in the array to maintain the
- sorted order.
-
- fill -- moves a single item into all of the elements of
- an array
-
- shuffle -- randomly permutes ("unsorts") the elements of an
- array
-
- subfill -- moves a single item into all of the elements of a
- subarray of the base array
-
- submove -- moves the elements of the source array into a
- subarray of the destination array (or, the
- elements of a subarray of the source to the
- destination array)
-
- xsubmove -- moves the elements of a subarray of the source
- array into the elements of a subarray of the
- destination.
-
-
- CONCEPTS
-
- The ARRAYs to be manipulated are passed as "untyped vars" to
- these routines. (In the "Interface" section, these arrays are
- called "base", "source" or "destination".) These routines will
- treat the ARRAYs as if they were declared to be of type:
-
- ArrayType = ARRAY [1..MaxArray] OF ElementType
-
- Each ELEMENT of the ARRAY is presumed to be fixed size, and this
- size must be passed to the routines. (In the "Interface"
- section, if an ELEMENT needs to passed directly to a routine as
- an argument, it is passed as an untyped var called "key".) Also,
- the number of elements in the ARRAY must also be passed. For
- instance, to fill an array of real numbers with 0:
-
- var RealArray : array [1..10] of Real;
- x : real;
-
- x:=0;
- fill(RealArray,10,sizeof(real),x);
-
- A SUBARRAY is a "byte-slice" of an array. For instance, if
- "ElementType" is an "array [1..8] of byte", then a "subelement"
- would be any contiguous collection of bytes within the
- element, like 3,4 and 5. The SUBARRAY would be the collection of
- all of the subelements stored in an ARRAY. If "ElementType" is a
- record of fields, then a "subelement" would be any contigous
- group of fields.
-
- For sorting and searching, a COMPARISON FUNCTION must be passed
- to the routines. COMPARISON FUNCTIONs take two untyped vars,
- return a longint value, and must be declared "far" at
- compilation. (DIFFERENT! In C, only an integer-sized value is
- returned.) For instance, to sort the array of real numbers
- declared earlier:
-
- function RealCompare(var a,b):longint; far;
- begin
- if real(a)>real(b) then realcompare:=1
- else if real(a)<real(b) then realcompare:=-1
- else realcompare:=0;
- end;
-
- qsort(realarray,10,sizeof(real),realcompare);
-
-
-
- INTERFACE
-
- type comparefunc = function (var a,b{:element}):longint; {far;}
-
- Declares the type of the comparison function to passed to
- sorting and searching routines. CompareFunc's are
- user-defined functions that takes two arguments a and b. A
- and B must be typeless in the declaration, but otherwise are
- of the same type as the elements of the "base" array. For
- "qsort" and "bsearch", the function needs to return a
- negative integer if "A<B"; a positive integer if "A>B"; and 0
- if "A=B". For "lfind" and "lsearch", the function needs to
- return 0 if "A=B", and some non-zero integer if "A<>B".
-
-
- function bfind(var key{:element}, base{:array};
- length_base, sizeof_element:word;
- f:comparefunc):longint;
-
- Searches a sorted array for a "key" element. Return the index
- of its location, or the negative of the index of the largest
- element in the array that is smaller than the key (i.e., the
- element that you want to insert the new element after).
-
-
- function binsert(var key{:element}, base{:array};
- length_base, sizeof_element:word;
- f:comparefunc):longint;
-
- WARNING: This routine overwrites memory if used incorrectly.
-
- Inserts the key element into the correct position of an
- ordered array. Unlike "lsearch", which only adds the key if
- it's not already present, "binsert" ALWAYS inserts a new
- element into the array. "Binsert" returns the index where the
- element is inserted.
-
-
- function bsearch(var key{:element}, base{:array};
- length_base, sizeof_element:word;
- f:comparefunc):word;
-
- "Bsearch" attempts to locate the "key" element within the previously
- SORTED array "base". If successful, the index of the found element is
- returned; otherwise, 0 is returned to indicate that the
- element is not present.
-
-
- procedure fill(var key{:element}, destination{:array};
- count, sizeof_element:word);
-
- WARNING: This routine overwrites memory if used incorrectly.
-
- Moves the "key" element to the first "count" indices in the
- "destination" array.
-
-
- function lfind(var key{:element}, base{:array};
- length_base, sizeof_element:word;
- f:comparefunc):word;
-
- "Lfind" attempts to locate the "key" element within the array "base".
- If successful, the index of the found element is returned; otherwise, 0
- is returnd to indicate the element is not present.
-
-
- function lsearch(var key{:element}, base{:array};
- length_base, sizeof_element:word;
- f:comparefunc):word;
-
- WARNING: This routine overwrites memory if used incorrectly.
-
-
- var monitor : procedure;
- procedure nullmonitor;
-
- "Monitor" and "NullMonitor" were debugging devices developed
- in the process of putting together the ASORTS unit. They can
- be optionally declared by defining a compilation variable
- "MONITOR". Every time that the "Qsort" algorithm swaps a pair
- of array elements, the "monitor" procedure is called. This
- will allow the user to watch the progress of the sort. This
- is of marginal practical value, and by default, these two
- identifiers are not declared. Calling "NullMonitor" will turn
- off monitoring even if the "monitor" procedure variable is
- present.
-
-
- procedure qsort(var base {:array};
- length_base, sizeof_element:word;
- f:comparefunc);
-
- WARNING: This routine overwrites memory if used incorrectly.
-
- "Qsort" reorders the elements of the "base" array using a quicksort
- algorithm. The function "f" is used to compare two elements of the
- array, and must return a negative number if the first argument is "less
- than" the second, a postive number if the first argument is "greater
- than" the second, and zero if the two arguments are "equal".
-
-
- procedure shuffle(var base{:array};
- length_base, sizeof_element:word);
-
- WARNING: This routine overwrites memory if used incorrectly.
-
- Randomly permutes ("unsorts") the elements of an array. The
- SYSTEM "Randomize" procedure should be called at least once
- in a program that shuffles an array.
-
-
- procedure subfill(var key{:subelement}, destination{:subarray};
- count, sizeof_key, sizeof_element:word);
-
- WARNING: This routine overwrites memory if used incorrectly.
-
- Partially fills an array with the "key". The address of
- "Destination" should be the address of the first byte in the
- subarray. The portion of the array outside of the subarray is
- left unchanged.
-
-
- procedure submove(var source{:[sub]array},
- destination{:[sub]array};
- count,
- sizeof_source_element,
- sizeof_destination_element:word);
-
- WARNING: This routine overwrites memory if used incorrectly.
-
- If the size of the source elements are smaller than that of
- the destination elements, moves the first "count" elements of
- the source into a subarray of the same size in destination.
- If larger, only moves that portion of the source that will
- fill the first "count" elements of the destination. If equal
- in size, does a simple "move" of the bytes.
-
-
- procedure xsubmove(var source{:subarray}, destination{:subarray};
- count, sizeof_source_element,
- sizeof_destination_element,
- sizeof_subelement:word);
-
- WARNING: This routine overwrites memory if used incorrectly.
-
- Moves a subarray from the source to the destination. The size
- of the subelements is presumed to be the same in both
- subarrays. "XsubMove" does not check to make sure that the
- sizes are consistent.
-
-