/* File LinkedStack.c Source code for a stack implemented using a singly linked list. Code taken from MCS 360 textbook (Data Structures and Program Design in C, Second Edition, by Kruse, Tondo, and Leung), pages 83-85, but missing code has been filled in and the code has been modified i) 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 ArrayStack.c */ typedef struct Node { StackEntry entry; /* One entry on the stack. */ struct Node *next; /* Ptr to next node toward bottom. */ } Node; struct Stack { Node *top; /* Pointer to top node of stack */ int size; /* Current size (height) of stack. */ }; static Node *freelist = NULL; static Node *MakeNode( StackEntry item, Node *next) { Node *nodepointer; if ( freelist != NULL ) { nodepointer = freelist; freelist = freelist->next; } else nodepointer = (Node *)checked_malloc(sizeof(Node)); nodepointer->entry = item; nodepointer->next = next; return nodepointer; } static void freeNode( Node *nodepointer) { nodepointer->next = freelist; freelist = nodepointer; } /* Creates a new stack, initializes it to empty, and returns a pointer to it. */ Stack *CreateStack() { Stack *newStack = (Stack *)checked_malloc(sizeof(Stack)); newStack->top = NULL; newStack->size = 0; return newStack; } /* Destroys the stack s by freeing all memory used by it. */ void DestroyStack( Stack *s) { Node *p = s->top; while ( p != NULL ) { Node *q = p->next; free( p); p = q; } free(s); } void Push( StackEntry item, Stack *s) { s->top = MakeNode( item, s->top); ++s->size; } void Pop( StackEntry *item, Stack *s) { Node *removedNode; if ( StackEmpty(s) ) err_mesg( "Pop()", "Stack is empty."); removedNode = s->top; s->top = removedNode->next; --s->size; *item = removedNode->entry; freeNode( removedNode); } Boolean StackEmpty( const Stack *s) { return s->top == NULL; } void ClearStack( Stack *s) { s->top = NULL; s->size = 0; } int StackSize( const Stack *s) { return s->size; } void StackTop( StackEntry *item, const Stack *s) { if ( StackEmpty(s) ) err_mesg( "StackTop()", "Stack is empty."); *item = s->top->entry; } void TraverseStack( Stack *s, void (*visit)(StackEntry)) { Node *p; for ( p = s->top ; p != NULL ; p = p->next ) visit( p->entry); } /* Frees stack memory that is allocated but not currently in use. With the linked representation of a stack, it frees all nodes on the freelist. Since all stacks share a common freelist, the Stack parameter s is not used. (It may be NULL.) */ int freeStackMemory( Stack *s) { Node *p = freelist, *q; int count = 0; freelist = NULL; while ( p != NULL ) { q = p->next; free(p); p = q; ++count; } return count; }