home *** CD-ROM | disk | FTP | other *** search
- QKSORT Documentation
- --------------------
-
- QKSORT is a small unit for Turbo Pascal 5.0 that implements two routines
- similar to ones found in the Turbo C library: qsort and bsearch.
-
- qsort performs in-memory sorting of an array with the Quicksort algorithm.
- arrays of any type, up to a maximum of 32767 elements, may be sorted.
-
- bsearch performs a binary search of an array. The array must be in sorted
- order, and may be of any type, up to a maximum of 32767 elements.
-
- As in the Turbo C functions, qsort and bsearch are "engines" which rely on
- a user-written comparison function to determine the proper sort sequence.
- This gives you tremendous flexibility, because you don't need a separate
- sort or search routine for each data structure. Only the comparison
- function needs to change.
-
-
- Defining the comparison function
- --------------------------------
-
- Your comparison function MUST be written with the following format:
-
- {$F+} { must be a far call }
- function mycomp(var p1,p2) : integer;
-
- begin
- ...
- mycomp := ...
- end;
- {$F-}
-
- You may use any function name you wish, but it MUST be a far function
- {$F+}, it MUST have two untyped var parameters (p1 and p2), and it MUST
- return an integer.
-
- The comparison function must return an integer based on the sequence of the
- two records:
-
- <0 record p1 comes BEFORE record p2 in sequence
- 0 record p1 and record p2 are equivalent in terms of sequence
- >0 record p1 comes AFTER record p2 in sequence
-
-
- Using qsort
- -----------
-
- Usually, you will be sorting or searching on arrays of records. Here is an
- example showing how a comparsion function would be written. Suppose you
- have a mailing list that you want to sort in ascending order of last name:
-
- uses
- qksort;
-
- type
- mail_rec = record { mailing list record }
- id : integer; { ID number }
- lname : string[24]; { last name }
- fname : string[12]; { first name }
- .
- . (additional fields in record)
- .
- end;
-
- var
- mail_list = array[0..100] of mail_rec;
-
-
- function mail_comp(var p1,p2) : integer;
-
- { comparison function to sort mailing list in ascending order of
- last name. }
-
- begin
- if mail_rec(p1).lname < mail_rec(p2).lname then
- mail_comp := -1
- else if mail_rec(p1).lname > mail_rec(p2).lname then
- mail_comp := 1
- else
- mail_comp := 0;
- end;
-
-
- Notice the use of "mail_rec(p1)". This typecasting is necessary so that
- Turbo can figure out the type of the variables being compared, since they
- are passed as untyped parameters.
-
- Notice also that this function could easily be changed to sort on a
- different field, or to sort in descending order instead of ascending order.
-
- Now, to actually sort the records, assuming the number of actual records
- in the array is in the variable numrec, the call is:
-
- qsort(mail_list,nr,sizeof(mail_rec),mail_comp);
-
- You should always use the sizeof() function to pass the record size. In
- that way, if you ever change the record structure, your sort call will
- not need to be modified.
-
-
- Using bsearch
- -------------
-
- bsearch performs a binary search on a sorted array for a given key value.
- Note that the array must be sorted; otherwise bsearch will not work
- properly.
-
- The call to bsearch is similar to the call to qsort, except that you need
- to specify the key value as the first parameter. Using the example above,
- if you wanted to search for a key value stored in the variable k, the call
- would be:
-
- i := bsearch(k,mail_list,nr,sizeof(mail_list),mail_comp);
-
- The function returns either a record number (starting at 0) if the key was
- found, or -1 if the key was not found. (Note: this is different that the
- Turbo C function return of a pointer.)
-
- IMPORTANT NOTE: bsearch does not care what the type of the key value is.
- It is the responsibility of the comparison function to know that the SECOND
- parameter passed is the key value, while the first parameter is a record.
- This leaves you with two choices:
-
- Method 1 is to pass a simple key value (a string in the example shown), in
- which case the comparison function must be aware that the two parameters
- being passed are of different types.
-
- Method 2 is to pass an entire record of the same type as the array being
- searched. This record only needs to have the key value set. The advantage
- of method 2 is that you can use the same comparison function for both qsort
- and bsearch.
-
- Using method 2 on the example above, the value k would have been defined
- as:
-
- var
- k : mail_rec; { a single record }
-
- .
- .
- .
-
- k.lname := 'Schwartz'; { the key I'm looking for }
- i := bsearch(k,mail_list,nr,sizeof(mail_list),mail_comp);
-
-
- Good luck with these routines. I hope you find them useful.
-
- -- Bob Showalter
- CompuServe ID 72220,466
-