L-30 MCS 360 Monday 31 March 2003

In this lecture we considered sorting using a priority queue and a binary tree. The straight selection sort in between can be regarded as a possible implementation of the delete operations in a priority queue.

For each sort we counted the number of comparisons.

1. Sort with Priority Queue

3.1 priority_queue.h

/* L-30 MCS 360 Monday 30 March 2003
 *   Declaration of a priority queue as a list. 
 *   Adapted from Lecture 13.   */

#define elements int

typedef struct list priority_queue;
/* a priority queue is a list of elements */

struct list
{
   elements item;         /* first elements in list */
   priority_queue *next;  /* points to next elements */
};

int length ( priority_queue *q );
/* postcondition: returns number of elements in q */

priority_queue *delete_element ( priority_queue *q, elements *e, int *flag );
/* precondition: length(q) > 0;
 * postcondition: smallest element is removed from priority queue q,
 *                if empty(q), *flag == -1, otherwise *flag == 0; */

priority_queue *insert_element ( priority_queue *q, elements e );
/* postcondition: element e is inserted to the priority queue q; */

void write_elementss ( priority_queue *q );
/* postcondition: writes all elementss in the queue to the screen; */

3.2 priority_queue.c

/* L-30 MCS 360 Monday 31 March 2003
 *   implementation of the operations in the priority queue */

#include <stdlib.h>
#include "priority_queue.h"

int length ( priority_queue *q )
{
   if (q == NULL)
      return 0;
   else
      return 1 + length(q->next);
}

priority_queue *delete_element ( priority_queue *q, elements *e, int *flag )
{
   if (q == NULL) 
   {
      *flag = -1;
      return q;
   }
   else
   {
      priority_queue *nq;

      *flag = 0;
      *e = q->item;
      nq = q->next;
      free(q);
 
      return nq;
   }
   
}

priority_queue *insert_element ( priority_queue *q, elements e )
{
   priority_queue *nq;

   nq = (priority_queue*) calloc(1,sizeof(priority_queue));
   nq->item = e;

   if (q == NULL)
   {
      nq->next = NULL;
      return nq;
   }
   else if (e < q->item)
   {
      nq->next = q;
      return nq;
   }
   else
   {
      priority_queue *previous = q;
      priority_queue *current = q->next;

      while (current != NULL)
      {
         if (e < current->item) break;
         previous = current;
         current = current->next;
      }
      previous->next = nq;
      nq->next = current;

      return q;
   }
}

void write_elements ( priority_queue *q )
{
   if (q != NULL)
   {
      elements e = q->item;
      printf(" %d ", e);
      write_elements(q->next);
   }
} 

3.3 pqsort.c

/* L-30 MCS 360 Monday 31 March 2003
 *   Simple program to use priority queue to sort.
 * The priority queue is taken from lecture 13.  */

#include <stdio.h>
#include "priority_queue.h"

int main ( void )
{
   priority_queue *q;
   int n,flag;

   printf("Give sequence of numbers, terminate with -1 :\n");

   q = NULL;

   do
   {
      scanf("%d", &n);
      if (n<0) break;
      q = insert_element(q,n);     
   } while (n >= 0);

   printf("The sorted sequence : \n");

   while (length(q) > 0)
   {
      q = delete_element(q,&n,&flag);     
      printf(" %d", n);
   }
   
   printf("\n");

   return 0;
}

2. Straight Selection Sort

/* L-30 MCS 360 Monday 31 March 2003
 *   Simple program to test selection sort.  */

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void random_vector ( int n, int m, int a[n] );
/* returns n random integers modulo m in a */

void print_vector ( int n, int a[n] );
/* writes the vector to screen */

void selection_sort ( int n, int a[n] );
/* simple implementation of selection sort */

int main ( void )
{
   int s,m;

   srand(time(NULL));

   printf("Give size of vectors to sort : ");
   scanf("%d", &s);
   printf("Give size of numbers in the vector : ");
   scanf("%d", &m);

   {
      int a[s];
      random_vector(s,m,a);
      print_vector(s,a);
      selection_sort(s,a);
      print_vector(s,a);
   }
      
   return 0;
}

void random_vector ( int n, int m, int a[n] )
{
   int i;
   for(i=0; i<n; i++) a[i] = rand() % m;
}

void print_vector ( int n, int a[n] )
{
   int i;
   for(i=0; i<n; i++) printf(" %d", a[i]);
   printf("\n");
}

void selection_sort ( int n, int a[n] )
{
   int i,j,ind,tmp;

   for(i=0; i<n-1; i++)
   {
      ind = i;
      for(j=i+1; <n; j++)
        if (a[j] < a[ind]) ind = j;

      if(ind != i)
      {
         tmp = a[i];
         a[i] = a[ind];
         a[ind] = tmp;
      }
   }
}

3. Sort with Binary Tree

/* L-30 MCS 360 Monday 31 March 2003
 *   Simple program to use a binary tree to sort.
 * The "ptree" is taken from lecture 19.  */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "ptree.h"

void random_vector ( int n, int m, int a[n] );
/* returns n random integers modulo m in a */

void print_vector ( int n, int a[n] );
/* writes the vector to screen */

void tree_sort ( int n, int a[n] );
/* uses binary tree to sort the elements in a,
 * note that this sort removes duplicates */

tree *insert_element ( tree *t, int n );
/* sorted insert of element */

void write_elements ( tree *t );
/* writes the elements in order */

void store_elements ( tree *t, int n, int a[n], int *p );
/* stores elements of the tree in the array a,
 * starting at position p */

void sort_user_data ( void );
void sort_random_data ( void );

int main ( void )
{
   int answer;

   printf("MENU to test sort with a binary tree.\n");
   printf("  1. sort user given data; \n");
   printf("  2. sort randomly generate data; \n");
   printf("Type 1 or 2 to make a choice : ");
   scanf(" %d", &answer);

   if (answer == 1)
      sort_user_data();
   else if (answer == 2)
      sort_random_data();
   else 
      printf("invalid answer\n");

   return 0;
}

tree *insert_element ( tree *t, int n )
{
   if (empty(t) == 1)
      t = create(n);

   if (n < info(t))
      add_left(t,insert_element(left(t),n));
   else if (n > info(t))
      add_right(t,insert_element(right(t),n));

   return t;
}

void write_elements ( tree *t )
{
   if (empty(t) == 0)
   {
      write_elements(left(t));
      printf(" %d", info(t));
      write_elements(right(t));
   }
}

void store_elements ( tree *t, int n, int a[n], int *p )
{
   if (empty(t) == 0)
   {
      store_elements(left(t),n,a,p);
      a[(*p)++] = info(t);
      store_elements(right(t),n,a,p);
   }
}

void random_vector ( int n, int m, int a[n] )
{
   int i;
   for(i=0; i<n; i++) a[i] = rand() % m;
}

void print_vector ( int n, int a[n] )
{
   int i;
   for(i=0; i<n; i++) printf(" %d", a[i]);
   printf("\n");
}

void tree_sort ( int n, int a[n] )
{
   tree *t = NULL;
   int i;

   for(i=0; i<n; i++)
      t = insert_element(t,a[i]);

   i=0;
   store_elements(t,n,a,&i);
   while (i<n) a[i++] = -1;
}

void sort_user_data ( void )
{
   tree *t = NULL;
   int n;

   printf("Give sequence of numbers, terminate with -1 :\n");

   t = NULL;

   do
   {
      scanf("%d", &n);
      if (n<0) break;
      t = insert_element(t,n);     
   } while (n >= 0);

   printf("The sorted sequence : \n");

   write_elements(t);
   
   printf("\n");
}

void sort_random_data ( void )
{
   int s,m;

   srand(time(NULL));

   printf("Give size of vectors to sort : ");
   scanf("%d", &s);
   printf("Give size of numbers in the vector : ");
   scanf("%d", &m);

   {
      int a[s];
      random_vector(s,m,a);
      print_vector(s,a);
      tree_sort(s,a);
      print_vector(s,a);
   }
}