L-13 MCS 360 Wednesday 12 February 2003
In this lecture we use linked lists to implement
priority queues.
0. The Abstract Data Type of a priority queue
abstract typedef <<elements>> priority_queue;
/* a priority queue is a sequence of elements */
abstract int length ( priority_queue q );
postcondition: returns number of elements in q */
abstract int delete_element ( priority_queue q, elements e );
precondition: length(q) > 0;
postcondition: smallest element is removed from priority queue q,
returns -1 if length(q) == 0, returns 0 otherwise;
abstract void insert_element ( priority_queue q, elements e );
postcondition: element e is inserted to the priority queue q;
1. the file priority_queue.h
/* L-13 MCS 360 Wednesday 12 February 2003
* Declaration of a priority queue as a list.
* Compared to the ADT we had to change the declaration of
* those functions which modify the priority queue,
* because call by reference in C simply copies
* the value of the pointer to the argument of the function.
* Call-by-reference in C is call-by-value on addresses. */
typedef struct
{
int number; /* number of job */
float duration; /* duration of job */
} job;
typedef struct list priority_queue;
/* a priority queue is a list of jobs */
struct list
{
job item; /* first job in list */
priority_queue *next; /* points to next job */
};
int length ( priority_queue *q );
/* postcondition: returns number of elements in q */
priority_queue *delete_job ( priority_queue *q, job *j, int *flag );
/* precondition: length(q) > 0;
* postcondition: smallest job is removed from priority queue q,
* if empty(q), *flag == -1, otherwise *flag == 0; */
priority_queue *insert_job ( priority_queue *q, job j );
/* postcondition: job j is inserted to the priority queue q; */
void write_jobs ( priority_queue *q );
/* postcondition: writes all jobs in the queue to the screen; */
2. the file priority_queue.c
/* L-13 MCS 360 Wednesday 12 February 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_job ( priority_queue *q, job *j, int *flag )
{
if (q == NULL)
{
*flag = -1;
return q;
}
else
{
priority_queue *nq;
*flag = 0;
*j = q->item;
nq = q->next;
free(q);
return nq;
}
}
priority_queue *insert_job ( priority_queue *q, job j )
{
priority_queue *nq;
nq = (priority_queue*) calloc(1,sizeof(priority_queue));
nq->item = j;
if (q == NULL)
{
nq->next = NULL;
return nq;
}
else if (j.duration < q->item.duration)
{
nq->next = q;
return nq;
}
else
{
priority_queue *previous = q;
priority_queue *current = q->next;
while (current != NULL)
{
if (j.duration < current->item.duration) break;
previous = current;
current = current->next;
}
previous->next = nq;
nq->next = current;
return q;
}
}
void write_jobs ( priority_queue *q )
{
if (q != NULL)
{
job j = q->item;
printf(" job %d has duration %f\n", j.number, j.duration);
write_jobs(q->next);
}
}
3. the file use_priority_queue.c
/* L-13 MCS 360 Wednesday 12 February 2003
* Simple interactive program to test the priority queue. */
#include <stdio.h>
#include "priority_queue.h"
int main ( void )
{
priority_queue *q;
char action;
job j;
int jobnb = 0;
int check;
q = NULL;
do
{
printf("\nNumber of jobs in priority queue : %d.\n",length(q));
write_jobs(q);
printf("\nChoose one of the following :\n");
printf(" 0. leave this program\n");
printf(" 1. insert job to the queue\n");
printf(" 2. delete job from the queue\n");
printf("Make your choice : ");
scanf(" %c", &action);
switch(action)
{
case '0': printf("\n Bye bye.\n\n");
break;
case '1': j.number = jobnb++;
printf("\n Give duration : ");
scanf("%f", &j.duration);
q = insert_job(q,j);
break;
case '2': q = delete_job(q,&j,&check);
if (check == 0)
printf("\n Deleted job %d with duration %f.\n",
j.number, j.duration);
else
printf("\n There were no jobs to delete.\n");
break;
default: printf("\n Invalid choice, try again...\n");
}
}
while (action != '0');
return 0;
}