Originally Posted by
peripatein
Furthermore, I'd now like to create a function the purpose of which is to delete from the Order's queue a specific order for the driver with the given name. May I write it thus? (Please note that the declarations themselves of the relevant struct and the function are a given)
Code:
typedef struct order{
int orderID;
int isSpecific;
char specificDriver[101];
struct order* next;
}Order;
int removeOrderByName(TaxiSystem * system, char * name){
while (system->ordersQueue != NULL && !strcmp(system->ordersQueue->specificDriver, name))
system->ordersQueue = system->ordersQueue->next;
free(system);
return 1;
}
Nope, this breaks all over the place (you haven't tested it, have you? ;-)
Perhaps you should step back a bit, and re-familiarize yourself with pointers and linked lists (via the relative chapters in your textbook, for example... or any other source).
However, I can't really understand why they are forcing you to use a queue implementation that is not utilizing a head and a tail pointer, which is the norm.
Anyway, here's a possible implementation of a function that removes a node from the drivers queue (which is a vanilla linked-list) based on the name.
Code:
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;
}
The tricky part is that we need 2 temporary pointers when walking the list, because if the desired node is found, then before freeing it we need to link its previous node with its next node. Since singly linked lists do not have prev pointers in their node, this approach is necessary.
It also means that we can treat the first node as a special case, in an effort to simplify the code.
A similar implementation could be something like the following...
Code:
int driversQ_delete_driver_by_name( Driver **driversQ, const char *name )
{
Driver *cur = NULL; /* current node */
Driver *prv = NULL; /* node before current */
if ( !driversQ || !name )
return 0;
/* walk the queue until either NULL or a node containing 'name' is found */
cur = *driversQ;
while ( cur && 0 != strncmp(cur->name, name, 101) ) {
prv = cur;
cur = cur->next;
}
if ( !cur ) /* name was not found */
return 0;
if ( cur == *driversQ ) /* name was found in first node */
*driversQ = (*driversQ)->next;
else /* name was found elsewhere */
prv->next = cur->next;
free( cur );
return 1;
which is pretty much the same thing with slightly different wording.
It should be easy to modify it for any of the queues in your exercise, or any other single linked list for that matter (but try them with several test cases, because I haven't).
PS. Actually, the Internet is full of code snippets and even full programs showing this kind of stuff.