//----------------------------------------------------------------------------- // Queue.c // Implementation file for Queue ADT //----------------------------------------------------------------------------- #include #include #include #include #include "Queue.h" // structs -------------------------------------------------------------------- // private Node type typedef struct Node{ QueueElement data; struct Node* next; } Node; // private QueueObj type typedef struct QueueObj{ Node* front; Node* back; int length; } QueueObj; // Constructors-Destructors --------------------------------------------------- // newNode() // Returns a pointer to new Node object. Initializes next and data fields. Node* newNode(QueueElement data){ Node* N = malloc(sizeof(Node)); assert( N!=NULL ); N->data = data; N->next = NULL; return(N); } // newQueue() // Returns reference to new empty Queue object. Queue newQueue(){ Queue Q; Q = malloc(sizeof(QueueObj)); assert( Q!=NULL ); Q->front = Q->back = NULL; Q->length = 0; return(Q); } // freeQueue() // Frees all heap memory associated with Queue *pQ, and sets *pQ to NULL. void freeQueue(Queue* pQ){ if(pQ!=NULL && *pQ!=NULL) { while( !isEmpty(*pQ) ) { Dequeue(*pQ); } free(*pQ); *pQ = NULL; } } // Access functions ----------------------------------------------------------- // getFront() // Returns the value at the front of Q. // Pre: !isEmpty(Q) QueueElement getFront(Queue Q){ if( Q==NULL ){ fprintf(stderr, "Queue Error: getFront(): NULL Queue reference\n"); exit(EXIT_FAILURE); } if( isEmpty(Q) ){ fprintf(stderr, "Queue Error: getFront(): empty Queue\n"); exit(EXIT_FAILURE); } return(Q->front->data); } // getLength() // Returns the length of Q. int getLength(Queue Q){ if( Q==NULL ){ fprintf(stderr, "Queue Error: getLength(): NULL Queue reference\n"); exit(EXIT_FAILURE); } return(Q->length); } // isEmpty() // Returns true if Q is empty, otherwise returns false. bool isEmpty(Queue Q){ if( Q==NULL ){ fprintf(stderr, "Queue Error: isEmpty(): NULL Queue reference\n"); exit(EXIT_FAILURE); } return(Q->length==0); } // Manipulation procedures ---------------------------------------------------- // Enqueue() // Places new data at the back of Q. void Enqueue(Queue Q, QueueElement data){ Node* N = newNode(data); if( Q==NULL ){ fprintf(stderr, "Queue Error: Enqueue(): NULL Queue reference\n"); exit(EXIT_FAILURE); } if( isEmpty(Q) ) { Q->front = Q->back = N; }else{ Q->back->next = N; Q->back = N; } Q->length++; } // Dequeue() // Deletes data at front of Q. // Pre: !isEmpty(Q) void Dequeue(Queue Q){ Node* N = NULL; if( Q==NULL ){ fprintf(stderr, "Queue Error: Dequeue(): NULL Queue reference\n"); exit(EXIT_FAILURE); } if( isEmpty(Q) ){ fprintf(stderr, "Queue Error: Dequeue(): empty Queue\n"); exit(EXIT_FAILURE); } N = Q->front; if( getLength(Q)>=2 ) { Q->front = Q->front->next; }else{ Q->front = Q->back = NULL; } Q->length--; free(N); } // Other Functions ------------------------------------------------------------ // printQueue() // Prints a string representation of Q consisting of a comma separated list // of ints, surrounded by parentheses, to outfile. void printQueue(FILE* outfile, Queue Q){ Node* N = NULL; if( Q==NULL ){ fprintf(stderr, "Queue Error: printQueue(): NULL Queue reference\n"); exit(EXIT_FAILURE); } fprintf(outfile, "("); for( N = Q->front; N != NULL; N = N->next ){ fprintf(outfile, FORMAT"%s", N->data, N->next==NULL?"":", "); } fprintf(outfile, ")"); } // equals() // Returns true if A is same sequence as B, false otherwise. bool equals(Queue A, Queue B){ if( A==NULL || B==NULL ){ fprintf(stderr, "Queue Error: equals(): NULL Queue reference\n"); exit(EXIT_FAILURE); } bool eq = ( A->length == B->length ); Node* N = A->front; Node* M = B->front; while( eq && N!=NULL ){ eq = ( N->data==M->data ); N = N->next; M = M->next; } return eq; }