The Stack Data Structure Mugurel Ionu Andreica Spring 2012
Operations push(x) –Adds the element x at the top of the stack pop() –Removes the element from the top of the stack and returns it –Returns an error if the stack is empty peek() –Returns (but does not remove) the element at the top of the stack isEmpty() –Returns 1 if the stack is empty and 0 otherwise The axioms are given implicitly – they determine the expected behavior of the stack for a given sequence of operations –See the examples on the upcoming slides
Stack - Example
Stack – Array-based Implementation #include #define NMAX 100 template class Stack { private: T stackArray[NMAX]; int topLevel; public: void push(T x) { if (topLevel >= NMAX - 1) { fprintf(stderr, "Error The stack is full!\n"); return; } topLevel++; stackArray[topLevel] = x; } T pop() { if (isEmpty()) { fprintf(stderr, "Error The stack is empty!\n"); T x; return x; } T x = stackArray[topLevel]; topLevel--; return x; } T peek() { if (isEmpty()) { fprintf(stderr, "Error The stack is empty!\n"); T x; return x; } return stackArray[topLevel]; } int isEmpty() { return (topLevel < 0); } Stack() { // constructor topLevel = -1; } // the stack is empty in the beginning }; int main() { Stack s; s.push(7); s.push(3); s.push(10); s.push(13); s.push(20); s.push(9); s.push(1); printf("%d\n", s.pop()); printf("%d\n", s.peek()); printf("%d\n", s.peek()); printf("%d\n", s.pop()); printf("%d\n", s.peek()); s.push(100); printf("%d\n", s.pop()); return 0; }
Paranthesis Checking Given a string S composed of the characters ‘(‘, ‘)’, ‘[‘, ‘]’, ‘{‘, ‘}’ (round bracket, square bracket and curly bracket), determine if the parantheses are correctly balanced S=“([()[{([]()){}}[[]]]{}])[]({})” is correctly balanced S1=“([]({)})”, S2=“[{{}(())([]{“, S3=“[(){}]]” are not correctly balanced Algorithm –We use a stack –We traverse the string from left to right We push on the stack every open bracket For every closed bracket, the bracket at the top of the stack must be an open bracket of the same type (and the stack must not be empty) => then we pop the open bracket from the stack In the end, the stack must be empty
Paranthesis Checking - Implementation #include // copy & paste the definition of the Stack class char s[200]="([{()[]}(()[{}()])])(){}[{{()[]}()}]"; int error = 0; int main() { Stack stk; for (int i = 0; i < strlen(s); i++) { if (s[i] == '(' || s[i] == '[' || s[i] == '{') stk.push(s[i]); else if (stk.isEmpty()) { fprintf(stderr, "Error Empty stack\n"); error = 1; break; } else { if ((s[i] == ')' && stk.peek() != '(') || (s[i] == ']' && stk.peek() != '[') || (s[i] == '}' && stk.peek() != '{')) { fprintf(stderr, "Error Wrong paranthesis\n"); error = 1; break; } stk.pop(); } if (!error && !stk.isEmpty()) fprintf(stderr, "Error The stack is not empty at the end\n"); else if (!error) printf("OK\n"); return 0; }
Header with the Stack Class Definition Definition of the Stack class must be copy-pasted in every program in which it is used => annoying + prone to mistakes (maybe we do not copy-paste everything, or we copy-paste more than we need) Elegant solution: define the Stack class in a header file (e.g. mystack.h) Any program that uses the Stack class will include the header file –#include “mystack.h” (or #include ) –we will proceed similarly for the upcoming data structures