TIP: Click on subject to list as thread! ANSI
echo: c_echo
to: DAVID NOON
from: GEORGE WHITE
date: 1998-04-09 22:08:00
subject: Multiple Key sorts 1/

Hi David,
You wrote to me:
DN>DN>Ugh! That has even more iterations than genuine bubble sort.
DN>GW>You can't count! It has _exactly_ the same number :-)
DN>I don't think so. Bubble sort's inner loop is bounded by the current index
DN>of the outer loop. Tom's algorithm always uses the upper bound of the 
rray
DN>for the inner loop, even when the outer loop's index is a 0.
Sure it is, but you _still_ can't count :-). Bubble sort always starts
the inner loop from zero (things bubble _up_) and decrements the upper
bound, while Toms increments the start of the inner loop (things are
moved _down_) and retains the upper bound. Tom has an error in the
initialisation of the inner loop, it should be the outer loop value + 1,
and the outer loop should terminate one earlier too...
DN>DN>This is _guaranteed_ to perform n**2 comparisons, even when the data 
re
DN>DN>already ordered. That is twice as slow as bubble sort's worse case.
DN>GW>It also performs the same number of comparisons! :-)
DN>No. Same again, since it is 1 comparison per iteration.
See above :-).

DN>GW>Or even the version in SNIPPETS, which takes the same parameter list as
DN>GW>the standard library qsort().
DN>But calling a function to do comparisons is one of the things that slows
DN>down qsort(), whatever the internal algorithm. That is why I would never 
use
DN>qsort() or a clone, but would instantiate the template.
But for generalised sorting a struct on two separate keys, or of two
related but distinct sets of data, being able to change the comparison
routine (see code ) or replace the swap routine has much going for it.
Mind you, sorting data on two separate keys is the _major_ limitation of
quicksort, as it does _not_ keep items with the same key in the same
order as in the original data. So, if sorting data on two or more keys,
a different sort is required and neither quicksort or Shellsort are
suitable (but insertion sort is ).
Code? Oh! Yes :-)
Here is a demonstration test harness using the SNIPPETS sorts :-)
/*
        Copyright 1998 G. White
        Code donated to the Public Domain, use as you will.
    Normally generates a set of test data, one element of which is the
    initial sequence.
    The object is to get the data sorted with index as the primary sort,
    key as the secondary sort (all items with the same index to have
    key in sequence) and keeping all data with the same index and key
    in the initial sequence.
    So for each sort tested the data is first sorted on key and then on 
ndex.
    The test functions check the sorted data for conformance with the
    requirements and normally the number of out of sequence elements
    is displayed.
    If the output is re-directed to a file an expanded output to the
    file shows the out of sequence data pairs.
    Portability: fstat() is POSIX but not ANSI.
*/
/* sort test harness */
#include 
#include 
#include 
#include 
#include 
#include "snipsort.h"
#define DATA_SIZE 4000  /* Make this smaller to speed things up */
#define TEST_END        30
int     compare_index (const void *a,const void * b);
int     compare_key (const void *a,const void * b);
int     check_data (int sort_len);      /* Counts the sequence errors */
void    show_diff (int sort_len);       /* Shows the sequence errors */
struct  test_struct {
        short   key;
        short   index;
        short   sequence;
        };
struct test_struct ref_strct[DATA_SIZE];
struct test_struct sort_strct[DATA_SIZE];
int main (void)
{
int     counter,sort_len,redir = 0;
struct  stat    file_stat;
time_t  curr_time;
fstat (fileno (stdout),&file_stat);
if (file_stat.st_mode & S_IFREG)
    redir = 1;
sort_len = DATA_SIZE;
if (redir)
    printf ("\n\nData generated on %s",ctime (&curr_time));
/* Set up the initial data */
for (counter = 0;counter < sort_len;counter++)
    {
    ref_strct[counter].key = rand ()/100;
    ref_strct[counter].index = rand ()/100;
    ref_strct[counter].sequence = counter;
    }
printf ("\n\nStructure sort tests.");
do
    {
    printf ("\n %5d ",sort_len);
/* Set up data to be sorted */
    memcpy (sort_strct,ref_strct,sort_len * sizeof (ref_strct[0]));
    if (redir)
        printf ("\nQsort");
    else
        printf (" Qsort");
    qsort (sort_strct,sort_len,sizeof (sort_strct[0]),compare_key);
    qsort (sort_strct,sort_len,sizeof (sort_strct[0]),compare_index);
    printf (" %4d seq",check_data (sort_len));
    if (redir)
        {
        show_diff (sort_len);
        printf ("\nShellsort");
        }
    else
        printf (" Shellsort");
>>> Continued to next message
 * SLMR 2.1a * Wastebasket: Something to throw things near.
--- Maximus/2 3.01
---------------
* Origin: DoNoR/2,Woking UK (44-1483-717905) (2:440/4)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.