/* File ArrayStack.c. Source code for a stack implemented using a resizable array. Code taken from MCS 360 textbook (Data Structures and Program Design in C, Second Edition, by Kruse, Tondo, and Leung), pages 83-85, but modified i) to use a resizable dynamic array, so there is no fixed limit on the stack size, ii) to allow use of a common header file for all stack representations (e.g., array and linked list). ii) to make use of the functions in mcs360.c. */ #include "mcs360.h" #include "Stack.h" /* Same header file included by LinkedStack.c */ struct Stack { int top; /* Current size of stack */ int capacity; /* Current size of dynam array. */ StackEntry *entry; /* Dynam array for stack entries. */ }; #define INITIAL_CAPACITY 16 /* Creates a new stack, initializes it to empty, and returns a pointer to it. */ Stack *CreateStack(void) { Stack *newStack = (Stack *)checked_malloc(sizeof(Stack)); newStack->top = 0; newStack->capacity = INITIAL_CAPACITY; newStack->entry = (StackEntry *)checked_malloc( newStack->capacity * sizeof(StackEntry)); return newStack; } /* Destroys the stack s by freeing all memory used by it. */ void DestroyStack( Stack *s) { free( s->entry); free(s); } void Push( StackEntry item, Stack *s) { StackEntry *newEntry; if ( s->top == s->capacity ) { newEntry = (StackEntry *)realloc( s->entry, 2 * s->capacity * sizeof(StackEntry)); if ( newEntry != NULL ) { s->entry = newEntry; s->capacity *= 2; } else { newEntry = (StackEntry *)realloc( s->entry, 3 * (s->capacity/2+1) * sizeof(StackEntry)); if ( newEntry != NULL ) { s->entry = newEntry; s->capacity = 3 * (s->capacity/2 + 1); } else {; s->entry = (StackEntry *)checked_realloc( s->entry, 6 * (s->capacity /5+1) * sizeof(StackEntry)); s->capacity = 6 * (s->capacity/5 + 1); } } } s->entry[s->top++] = item; } void Pop( StackEntry *item, Stack *s) { if ( StackEmpty(s) ) err_mesg( "Pop()", "Stack is empty."); *item = s->entry[--s->top]; } Boolean StackEmpty( const Stack *s) { return s->top == 0; } void ClearStack( Stack *s) { s->top = 0; } int StackSize( const Stack *s) { return s->top; } void StackTop( StackEntry *item, const Stack *s) { if ( StackEmpty(s) ) err_mesg( "StackTop()", "Stack is empty."); *item = s->entry[s->top-1]; } void TraverseStack( Stack *s, void (*visit)(StackEntry)) { int i; for ( i = StackSize(s)-1 ; i >= 0 ; --i ) visit( s->entry[i]); } /* Frees stack memory that is allocated but not currently in use. With the array representation of a stack, it resizes the array for stack s to make the capacity (allocated size of the array) equal to the current size of the stack. If s is NULL, no action is taken. The return value is the number of stack positions freed. */ int freeStackMemory( Stack *s) { int oldCapacity = s->capacity; int size = StackSize(s); if ( s == NULL ) return 0; if ( s->capacity > size ) { StackEntry *resizedArray = (StackEntry *)realloc( s->entry, size * sizeof(StackEntry)); if (resizedArray != NULL ) { s->entry = resizedArray; s->capacity = size; } } return oldCapacity - s->capacity; }