@peripatein:
I felt bad, so here is a sample program implementing the basic queue operations on a vanilla singly linked list, plus the function that deletes a driver by name (it may contains bugs)...
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct driver{
char name[101];
int priority;
struct driver *next;
}Driver;
/* ------------------------------------------------------------------
* Destroy the queue and set it to NULL
*/
void driversQ_free( Driver **driversQ )
{
Driver *temp = NULL;
if ( !driversQ )
return;
temp = *driversQ;
while ( *driversQ ) {
temp = (*driversQ)->next;
free( *driversQ );
*driversQ = temp;
}
return;
}
/* ------------------------------------------------------------------
* Create a node with the specified data and insert it at the back of the queue.
*/
int driversQ_enqueue( Driver **driversQ, const char *name, int priority )
{
Driver *node = NULL;
if ( !driversQ )
return 0;
/* create & set a new node */
node = malloc( sizeof(Driver) );
if ( !node )
return 0;
strncpy( node->name, name, 101 );
node->priority = priority;
node->next = NULL;
/* when queue is empty */
if ( !(*driversQ) ) {
*driversQ = node;
}
/* when queue already has at least one node */
else {
node->next = *driversQ;
*driversQ = node;
}
return 1;
}
/* ------------------------------------------------------------------
* Remove the front node of the queue.
*/
int driversQ_dequeue( Driver **driversQ )
{
Driver *cur = NULL;
Driver *nxt = NULL;
if ( !driversQ )
return 0;
if ( !(*driversQ) )
return 1;
/* when queue has only one node */
if ( !(*driversQ)->next ) {
free( *driversQ );
*driversQ = NULL;
return 1;
}
/* walk the queue until last valid node */
cur = *driversQ;
nxt = (*driversQ)->next;
while ( nxt->next ) {
cur = nxt;
nxt = nxt->next;
}
free(nxt);
cur->next = NULL;
return 1;
}
/* ------------------------------------------------------------------
* Starting from the back of the queue, delete the
* first node found to contain the specified name.
*/
int driversQ_delete_driver_by_name( Driver **driversQ, const char *name )
{
Driver *cur = NULL; /* current node */
Driver *nxt = NULL; /* node next to current */
if ( !driversQ || !(*driversQ) || !name)
return 0;
cur = *driversQ;
/* first node is treated as a special case */
if ( 0 == strncmp( (*driversQ)->name, name, 101) ) {
*driversQ = (*driversQ)->next;
free( cur );
return 1;
}
// walk the queue until either NULL or a node containing 'name' is found
nxt = cur->next;
while ( nxt && 0 != strncmp(nxt->name, name, 101) ) {
cur = nxt;
nxt = cur->next;
}
if ( !nxt ) // data was not found in list
return 0;
cur->next = nxt->next;
free( nxt );
return 1;
}
/* ------------------------------------------------------------------
* Print all nodes of the queue, back to front.
*/
void driversQ_print( const Driver *driversQ )
{
while ( driversQ ) {
printf( "%s %d\n", driversQ->name, driversQ->priority );
driversQ = driversQ->next;
}
putchar('\n');
}
/* ------------------------------------------------------------------
* Program entry point.
*/
int main( void )
{
int i;
Driver *driversQ = NULL;
const char *testname = "driver-1";
driversQ_enqueue( &driversQ, "driver-1", 0 );
driversQ_enqueue( &driversQ, "driver-2", 1 );
driversQ_enqueue( &driversQ, "driver-3", 0 );
driversQ_enqueue( &driversQ, "driver-4", 0 );
driversQ_print( driversQ );
if ( !driversQ_delete_driver_by_name(&driversQ, testname) ) {
printf( "Driver %s was not found\n", testname );
}
else {
driversQ_print( driversQ );
}
for (i=0; i < 3; i++) {
puts( "Dequeueing..." );
driversQ_dequeue( &driversQ );
driversQ_print( driversQ );
}
driversQ_free( &driversQ );
return 0;
}
EDIT:
The address of the queue's head pointer is passed to functions that may modify it (thus the double pointer declaration in the parameter list of those functions).