//----------------------------------------------------------------------------- // Stack.c // Implementation file for Stack ADT //----------------------------------------------------------------------------- #include #include #include #include #include "Stack.h" // structs -------------------------------------------------------------------- // private Node type typedef struct Node{ StackElement data; struct Node* next; } Node; // private StackObj type typedef struct StackObj{ Node* top; int height; } StackObj; // Constructors-Destructors --------------------------------------------------- // newNode() // Returns pointer to a new Node object. Initializes next and data fields. Node* newNode(StackElement data){ Node* N = malloc(sizeof(Node)); assert( N!=NULL ); N->data = data; N->next = NULL; return(N); } // newStack() // Returns reference to new empty Stack object. Stack newStack(void){ Stack S; S = malloc(sizeof(StackObj)); assert( S!=NULL ); S->top = NULL; S->height = 0; return(S); } // freeStack() // Frees all heap memory associated with Stack *pS, and sets *pS to NULL. void freeStack(Stack* pS){ if(pS!=NULL && *pS!=NULL){ while( !isEmpty(*pS) ){ pop(*pS); } free(*pS); *pS = NULL; } } // Access functions ----------------------------------------------------------- // getTop() // Returns the value at the top of S. // Pre: !isEmpty(S) StackElement getTop(Stack S){ if( S==NULL ){ fprintf(stderr, "Stack Error: getTop(): NULL Stack reference\n"); exit(EXIT_FAILURE); } if( isEmpty(S) ){ fprintf(stderr, "Stack Error: getTop(): empty Stack\n"); exit(EXIT_FAILURE); } return(S->top->data); } // getHeight() // Returns the height of S. int getHeight(Stack S){ if( S==NULL ){ fprintf(stderr, "Stack Error: getHeight(): NULL Stack reference\n"); exit(EXIT_FAILURE); } return(S->height); } // isEmpty() // Returns true if S is empty, otherwise returns false. bool isEmpty(Stack S){ if( S==NULL ){ fprintf(stderr, "Stack Error: isEmpty(): NULL Stack reference\n"); exit(EXIT_FAILURE); } return(S->height==0); } // Manipulation procedures ---------------------------------------------------- // push() // Places new data element on top of S. // Post: !isEmpty(S) void push(Stack S, StackElement data){ Node* N = newNode(data); if( S==NULL ){ fprintf(stderr, "Stack Error: push(): NULL Stack reference\n"); exit(EXIT_FAILURE); } if( isEmpty(S) ){ S->top = N; }else{ N->next = S->top; S->top = N; } S->height++; } // pop() // Deletes data element on top of S. // Pre: !isEmpty(S) void pop(Stack S){ Node* N = NULL; if( S==NULL ){ fprintf(stderr, "Stack Error: pop(): NULL Stack reference\n"); exit(EXIT_FAILURE); } if( isEmpty(S) ){ fprintf(stderr, "Stack Error: pop(): empty Stack\n"); exit(EXIT_FAILURE); } N = S->top; if( getHeight(S)>1 ) { S->top = S->top->next; }else{ S->top = NULL; } S->height--; free(N); } // Other Functions ------------------------------------------------------------ // printStack() // Prints a string representation of S consisting of a comma separated list // of ints, surrounded by parentheses, to outfile. void printStack(FILE* outfile, Stack S){ Node* N = NULL; if( S==NULL ){ fprintf(stderr, "Stack Error: printStack(): NULL Stack reference\n"); exit(EXIT_FAILURE); } fprintf(outfile, "("); for(N = S->top; N != NULL; N = N->next){ fprintf(outfile, FORMAT"%s", N->data, N->next==NULL?"":", "); } printf(")"); } // equals() // Returns true if A is same int sequence as B, false otherwise. bool equals(Stack A, Stack B){ if( A==NULL || B==NULL ){ fprintf(stderr, "Stack Error: equals(): NULL Stack reference\n"); exit(EXIT_FAILURE); } bool eq = ( A->height == B->height ); Node* N = A->top; Node* M = B->top; while( eq && N!=NULL) { eq = ( N->data==M->data ); N = N->next; M = M->next; } return eq; }