A
arnuld
This is my 3rd data structure. I am learning to implement most of the
data structures in C. Niklaus Wirth one said:
Algorithms + Data Structures = Programs
and it took me 3 years to know the truth behind his comment. I wrote a C
program (for my employer) which produced around 30 bugs just because I did
not know how to implement a Queue in C. As usual, I am posting it here to
get suggestions, advice on improving the program etc.(You know I Love that
/* A Queue implementation in C using doubly linked list. It has all of the operation required by section 2.4 of "Data Structures and
* Algorithms" written by by Aho Hopcraft and Ullman. The name sof the queue operations were taken from that book.
*
* VERSION 0.0
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* IN C, 0 always means success ( e.g. EXIT_SUCCESS ), so I always use 0 for true and everything else for false */
enum { VAL_TRUE = 0, VAL_FALSE = 1 };
enum { SIZE_ARR = 10 } ;
struct my_list
{
char arrc[SIZE_ARR];
struct my_list* next;
struct my_list* prev;
};
struct my_queue
{
struct my_list* head;
struct my_list* tail;
};
struct my_queue* enqueue( struct my_queue*, const char* );
struct my_queue* dequeue( struct my_queue* );
struct my_list* front( struct my_queue* );
struct my_queue* queue_new( void );
void make_null( struct my_queue* );
int is_empty( struct my_queue* );
void queue_print( struct my_queue* );
void queue_print_element( struct my_list* );
int main( void )
{
struct my_queue* m = queue_new();
queue_print( m );
enqueue( m, "comp" );
enqueue( m, "." );
enqueue( m, "lang" );
enqueue( m, "." );
enqueue( m, "c" );
queue_print( m );
dequeue( m );
dequeue( m );
dequeue( m );
queue_print( m );
printf("Front = ");
queue_print_element( front(m) );
printf("is_empty = %d\n", is_empty(m) );
return 0;
}
struct my_queue* enqueue( struct my_queue* s, const char* c )
{
struct my_list* p = malloc( 1 * sizeof *p );
/* Check 1: the new element just malloc()ed */
if( NULL == p )
{
fprintf(stderr, "LINE: %d, malloc() failed\n", __LINE__ );
return s;
}
if( strlen(c) < SIZE_ARR )
{
strcpy( p->arrc, c );
p->prev = p->next = NULL;
}
else
{
printf("Size of array of the element is larger than required\n");
free(p);
return s;
}
/* Check 2: the original queue */
if( NULL == s)
{
printf("LINE: %d, Queue not initialized\n", __LINE__ );
}
else if( NULL == s->head && NULL == s->tail )
{
/* printf("Adding First element to Queue\n"); */
s->head = s->tail = p;
}
else if( NULL == s->head || NULL == s->tail )
{
fprintf(stderr, "LINE: %d, one of head/tail is NULL while other is not, WHY ???\n", __LINE__ );
return s;
}
else
{
/* printf("Adding element to the tail\n"); */
s->tail->next = p;
s->tail = p;
}
return s;
}
struct my_queue* dequeue( struct my_queue* s )
{
struct my_list* r = NULL;
if( NULL == s)
{
printf("LINE: %d, Queue not initialized\n", __LINE__ );
}
else if( NULL == s->head && NULL == s->tail )
{
printf("There are no elements in the queue\n");
}
else if( NULL == s->head || NULL == s->tail )
{
fprintf(stderr, "LINE: %d, one of head/tail is NULL while other is not, WHY ???\n", __LINE__ );
}
else
{
/* printf("Removing element\n"); */
r = s->head;
s->head = s->head->next;
free(r);
}
return s;
}
void make_null( struct my_queue* s )
{
if( NULL == s )
{
printf("LINE: %d, Queue is already NULL\n", __LINE__ );
}
else
{
while( s->head ) dequeue(s);
}
}
struct my_list* front( struct my_queue* s )
{
return s->head;
}
int is_empty( struct my_queue* s )
{
if( NULL == s->head && NULL == s->tail )
{
return VAL_TRUE;
}
else if( NULL == s->head || NULL == s->tail )
{
fprintf(stderr, "LINE: %d, there is somethign wrong with the assignment of the queue's head/tail\n", __LINE__);
}
return VAL_FALSE;
}
struct my_queue* queue_new( void )
{
struct my_queue* p = malloc( 1 * sizeof *p );
if( NULL == p )
{
fprintf( stderr, "LINE: %d, malloc() failed, can not initialize queue\n", __LINE__ );
exit( EXIT_FAILURE );
}
p->head = p->tail = NULL;
return p;
}
void queue_print( struct my_queue* s )
{
struct my_list* p = NULL;
if( NULL == s )
{
printf("Can not print a NULL queue\n");
}
else
{
for( p = s->head; p; p = p->next )
{
queue_print_element(p);
}
}
printf("--------------------------------------\n");
}
void queue_print_element( struct my_list* p )
{
printf("arrc = [%s]\n", p->arrc);
}
====================== OUTPUT =======================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra double-LL_queue.c
[arnuld@dune programs]$ ./a.out
--------------------------------------
arrc = [comp]
arrc = [.]
arrc = [lang]
arrc = [.]
arrc = [c]
data structures in C. Niklaus Wirth one said:
Algorithms + Data Structures = Programs
and it took me 3 years to know the truth behind his comment. I wrote a C
program (for my employer) which produced around 30 bugs just because I did
not know how to implement a Queue in C. As usual, I am posting it here to
get suggestions, advice on improving the program etc.(You know I Love that
/* A Queue implementation in C using doubly linked list. It has all of the operation required by section 2.4 of "Data Structures and
* Algorithms" written by by Aho Hopcraft and Ullman. The name sof the queue operations were taken from that book.
*
* VERSION 0.0
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* IN C, 0 always means success ( e.g. EXIT_SUCCESS ), so I always use 0 for true and everything else for false */
enum { VAL_TRUE = 0, VAL_FALSE = 1 };
enum { SIZE_ARR = 10 } ;
struct my_list
{
char arrc[SIZE_ARR];
struct my_list* next;
struct my_list* prev;
};
struct my_queue
{
struct my_list* head;
struct my_list* tail;
};
struct my_queue* enqueue( struct my_queue*, const char* );
struct my_queue* dequeue( struct my_queue* );
struct my_list* front( struct my_queue* );
struct my_queue* queue_new( void );
void make_null( struct my_queue* );
int is_empty( struct my_queue* );
void queue_print( struct my_queue* );
void queue_print_element( struct my_list* );
int main( void )
{
struct my_queue* m = queue_new();
queue_print( m );
enqueue( m, "comp" );
enqueue( m, "." );
enqueue( m, "lang" );
enqueue( m, "." );
enqueue( m, "c" );
queue_print( m );
dequeue( m );
dequeue( m );
dequeue( m );
queue_print( m );
printf("Front = ");
queue_print_element( front(m) );
printf("is_empty = %d\n", is_empty(m) );
return 0;
}
struct my_queue* enqueue( struct my_queue* s, const char* c )
{
struct my_list* p = malloc( 1 * sizeof *p );
/* Check 1: the new element just malloc()ed */
if( NULL == p )
{
fprintf(stderr, "LINE: %d, malloc() failed\n", __LINE__ );
return s;
}
if( strlen(c) < SIZE_ARR )
{
strcpy( p->arrc, c );
p->prev = p->next = NULL;
}
else
{
printf("Size of array of the element is larger than required\n");
free(p);
return s;
}
/* Check 2: the original queue */
if( NULL == s)
{
printf("LINE: %d, Queue not initialized\n", __LINE__ );
}
else if( NULL == s->head && NULL == s->tail )
{
/* printf("Adding First element to Queue\n"); */
s->head = s->tail = p;
}
else if( NULL == s->head || NULL == s->tail )
{
fprintf(stderr, "LINE: %d, one of head/tail is NULL while other is not, WHY ???\n", __LINE__ );
return s;
}
else
{
/* printf("Adding element to the tail\n"); */
s->tail->next = p;
s->tail = p;
}
return s;
}
struct my_queue* dequeue( struct my_queue* s )
{
struct my_list* r = NULL;
if( NULL == s)
{
printf("LINE: %d, Queue not initialized\n", __LINE__ );
}
else if( NULL == s->head && NULL == s->tail )
{
printf("There are no elements in the queue\n");
}
else if( NULL == s->head || NULL == s->tail )
{
fprintf(stderr, "LINE: %d, one of head/tail is NULL while other is not, WHY ???\n", __LINE__ );
}
else
{
/* printf("Removing element\n"); */
r = s->head;
s->head = s->head->next;
free(r);
}
return s;
}
void make_null( struct my_queue* s )
{
if( NULL == s )
{
printf("LINE: %d, Queue is already NULL\n", __LINE__ );
}
else
{
while( s->head ) dequeue(s);
}
}
struct my_list* front( struct my_queue* s )
{
return s->head;
}
int is_empty( struct my_queue* s )
{
if( NULL == s->head && NULL == s->tail )
{
return VAL_TRUE;
}
else if( NULL == s->head || NULL == s->tail )
{
fprintf(stderr, "LINE: %d, there is somethign wrong with the assignment of the queue's head/tail\n", __LINE__);
}
return VAL_FALSE;
}
struct my_queue* queue_new( void )
{
struct my_queue* p = malloc( 1 * sizeof *p );
if( NULL == p )
{
fprintf( stderr, "LINE: %d, malloc() failed, can not initialize queue\n", __LINE__ );
exit( EXIT_FAILURE );
}
p->head = p->tail = NULL;
return p;
}
void queue_print( struct my_queue* s )
{
struct my_list* p = NULL;
if( NULL == s )
{
printf("Can not print a NULL queue\n");
}
else
{
for( p = s->head; p; p = p->next )
{
queue_print_element(p);
}
}
printf("--------------------------------------\n");
}
void queue_print_element( struct my_list* p )
{
printf("arrc = [%s]\n", p->arrc);
}
====================== OUTPUT =======================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra double-LL_queue.c
[arnuld@dune programs]$ ./a.out
--------------------------------------
arrc = [comp]
arrc = [.]
arrc = [lang]
arrc = [.]
arrc = [c]