Presentation is loading. Please wait.

Presentation is loading. Please wait.

Introduction to Stacks Chapter 2. Objectives Introduce abstract data types. Discuss implementation types. – Static – Dynamic – Contiguous Introduce the.

Similar presentations


Presentation on theme: "Introduction to Stacks Chapter 2. Objectives Introduce abstract data types. Discuss implementation types. – Static – Dynamic – Contiguous Introduce the."— Presentation transcript:

1 Introduction to Stacks Chapter 2

2 Objectives Introduce abstract data types. Discuss implementation types. – Static – Dynamic – Contiguous Introduce the Stack abstract data type. – Stack methods – LIFO strucutres – Stack frames Introduce enumerations and the enum keyword. Discuss public vs. private in designing a class. Introduce encapsulation. Implement a contiguous stack. Discuss applications of stacks. – System stack – RPN calculator – Matching brackets Discuss refinement process.

3 Homework Overview Written (max 12 points) – 2.1 E1 (a,b,c,d)(2 pts each) – 2.3 E1 (a,b)(5 pts) Programming (max 20 points) – 2.1 E2(5 pts) – 2.2 E2(15 pts) – 2.2 P2(5 pts) – 2.3 P2(5 pts) Group Project (12 points) – 2.2 E1 (a,b,c)(12 pts)

4 Data Structures An abstract data type is a description of the operations that a structure must support. – It does not specify how it is implemented. We may implement the structure in several different ways. – The implementations should be interchangeable. A static implementation’s size is fixed when the program compiles. – Generally faster code and easier to program – Examples: arrays, objects A dynamic implementation’s size can change. – More versatile – Examples: vector, list, etc. A contiguous implementation is one where all the data is stored at the same location in computer memory. This is necessarily static.

5 Stack Abstract Data Type Stack – think of a stack of books. We add or remove items at the top. This is a “last-in, first-out” (LIFO) structure. We push items onto the stack and pop items from the stack. C++ contains support for a stack container adaptor ( #include ). A stack would be useful in writing a program that reverses a list of numbers.

6 System Stack Your computer system uses a stack to keep track of function calls. Every time a function is called, a record representing the function (and all its local variables) is pushed onto the system stack. When the function terminates, it is popped of the stack. The top of the stack is the currently running function. LIFO is the correct model here. – When a function terminates and it is removed from the stack, the function that called it will be the new top.

7 STL Stacks #include using namespace std; int main() /* Pre: The user supplies an integer n and n decimal numbers. Post: The numbers are printed in reverse order. Uses: The STL class stack and its methods. */ { int n; double item; stack numbers; // declares and initializes a stack of numbers cout << "Type in an integer n followed by n decimal numbers." << endl << "The numbers will be printed in reverse order." << endl; cin >> n; for (int i = 0; i < n; i++){ cin >> item; numbers.push(item); } cout << endl << endl; while (!numbers.empty()){ cout << numbers.top() << " "; numbers.pop(); } cout << endl; }

8 Stack Abstract Data Type Methods supported: –push – add an entry –pop – remove an entry –top – value of the top entry –empty – is the stack empty? We can store any type of data in a stack. Templates could be useful here.

9 Stack Frames A stack frame is a representation of the contents of a stack at a given instant. stack operationstack frame s.push(‘A’); s.push(‘B’); s.pop();

10 Homework – Section 2.1 (page 56) Written – E1 (a, b, c, d) (written on paper) (2 pts each) Programming – E2 (email code) (5 pts)

11 Stack Header #include using namespace std; typedef char Stack_entry; // change type for different applications const int maxstack = 10; // small value for testing enum Error_code {success, overflow, underflow}; // The possible error conditions void print_error(const Error_code); /* Pre: None. Post: The value of the Error_code is printed out if it is success, overflow or underflow. */ class Stack { public: Stack(); // constructor bool empty() const; /* Pre: None. Post: If the Stack is empty, true is returned. Otherwise false is returned. */

12 Stack Header Error_code pop(); /* Pre: None. Post: If the Stack is not empty, the top of the Stack is removed. If the Stack is empty, an Error_code of underflow is returned.*/ Error_code top(Stack_entry &item) const; /* Pre: None. Post: If the Stack is not empty, the top of the Stack is returned in item. If the stack is empty an Error_code of underflow is returned. */ Error_code push(const Stack_entry &item); /* Pre: None. Post: If the Stack is not full, item is added to the top of the Stack. If the Stack is full, an Error_code of overflow is returned and the Stack is left unchanged. */ private: int count; Stack_entry entry[maxstack]; };

13 Enum Keyword The line enum Error_code {success, overflow, underflow}; creates a new data type called Error_code. Variable created using this type can only have three possible values: success, overflow, and underflow. We could just use values like 0, 1, and 2, but this makes the code more readable. We also do not need to remember that 1 means overflow.

14 Public Methods/Private Data Notice that the methods that modify and access the data are public. – We could change the implementation and, as long as these public methods still fulfill their described jobs, code that uses the structure should still compile and run. The data itself is private. – It can only be accessed using the public methods. – This part may change depending on the implementation.

15 Contiguous Stack Implementation #include "stack.h" void print_error(const Error_code err) /* Pre: None. Post: The value of the Error_code is printed out if it is success, overflow or underflow. */ { if (err == success) cout << "success"; if (err == overflow) cout << "overflow"; if (err == underflow) cout << "underflow"; } Error_code Stack::push(const Stack_entry &item) /* Pre: None. Post: If the Stack is not full, item is added to the top of the Stack. If the Stack is full, an Error_code of overflow is returned and the Stack is left unchanged. */ { Error_code outcome = success; if (count >= maxstack) outcome = overflow; else entry[count++] = item; return outcome; }

16 Contiguous Stack Implementation Error_code Stack::pop() /* Pre: None. Post: If the Stack is not empty, the top of the Stack is removed. If the Stack is empty, an Error_code of underflow is returned.*/ { Error_code outcome = success; if (count == 0) outcome = underflow; else --count; return outcome; } Error_code Stack::top(Stack_entry &item) const /* Pre: None. Post: If the Stack is not empty, the top of the Stack is returned in item. If the stack is empty an Error_code of underflow is returned. */ { Error_code outcome = success; if (count == 0) outcome = underflow; else item = entry[count - 1]; return outcome; }

17 Contiguous Stack Implementation bool Stack::empty() const /* Pre: None. Post: If the Stack is empty, true is returned. Otherwise false is returned. */ { bool outcome = true; if (count > 0) outcome = false; return outcome; } Stack::Stack() /* Pre: None. Post: The stack is initialized to be empty.*/ { count = 0; }

18 Encapsulation Notice that the methods are public functions with not preconditions. We do not want the code to crash or behave poorly if the methods are used in an unexpected manner. This is a form of defensive programming.

19 Homework – Section 2.2 (page 64) Programming – E2 (email code) (15 pts) – P2 (email code) (5 pts) Group Project – 2.2 E1 (a,b,c) (email code)(12 pts)

20 RPN Calculator A calculator that uses RPN (Reverse Polish Notation) maintains a stack of numbers. Numbers can be pushed directly onto the stack by the user. When the user selects a unary operator (sine, cosine, negation, etc.) the top entry is popped off the stack, the operation applied and the result push back on the stack. When the user selects a binary operation (+,-,*,/,^, etc.) the top two numbers are popped off the stack, the operation applied and the result push back onto the stack

21 RPN Example: Calculate (2.1+0.5)*5.3 The following is a series of stack frames showing the operation of RPN. Note the “top” of the stack is traditionally shown on the bottom in RPN. stack operationstack frame push 5.3 push 0.5 push 2.1 operation + operation * Note, with RPN we can avoid using parentheses. – People who spend the time getting comfortable with it and who can find and RPN calculator often prefer this convention.

22 RPN Program int main() /*Post: The program has executed simple arithmetic commands entered by the user. Uses: The class Stack and the functions introduction, instructions, do_command, and get_command. */ { Stack stored_numbers; introduction(); instructions(); while (do_command(get_command(), stored_numbers)); }

23 RPN Calculator char get_command() /* Post: Returns a command (?, =, +, -, *, /, q) entered by the user */ { char command; bool waiting = true; cout :"; while (waiting){ cin >> command; command = tolower(command); if (command == '?' || command == '=' || command == '+' || command == '-' || command == '*' || command == '/' || command == 'q') waiting = false; else { cout << "Please enter a valid command:" << endl << "[?]push to stack [=]print top" << endl << "[+][-][*][/] are arithmetic operations" << endl << "[Q]uit." << endl; } } return command; }

24 RPN Calculator bool do_command(char command, Stack &numbers) /* Pre: The first parameter specifies a valid calculator command. Post: The command specified by the first parameter has been applied to the Stack of numbers given by the second parameter. A result of true is returned unless command == 'q'. Uses: The class Stack. */ { double p, q; switch (command) { case '?': cout << "Enter a real number: " << flush; cin >> p; if (numbers.push(p) == overflow) cout << "Warning: Stack full, lost number" << endl; break; case '=': if (numbers.top(p) == underflow) cout << "Stack empty" << endl; else cout << p << endl; break;

25 RPN Calculator case '+': if (numbers.top(p) == underflow) cout << "Stack empty" << endl; else { numbers.pop(); if (numbers.top(q) == underflow) { cout << "Stack has just one entry" << endl; numbers.push(p); } else { numbers.pop(); if (numbers.push(q + p) == overflow) cout << "Warning: Stack full, lost result" << endl; } } break; // Add options for further user commands. case 'q': cout << "Calculation finished.\n"; return false; } return true; }

26 Homework – Section 2.3 (page 69) Written – E1 (written on paper) (5 pts) Programming – P1 (nothing to turn in) – P2 (email code) (5 pts)

27 Matching Brackets Another application of stacks is matching brackets in code (or English). Is the line {a=(b[0)+1];} legal? It has the matched pairs of brackets. – For every { there is a }. – For every ( there is a ). – For every [ there is a ]. Just counting the brackets is insufficient. When we encounter an opening bracket we push it onto a stack. When we encounter a closing bracket we pop the matching opening bracket off the stack. – If there is not a matching opening bracket then there is a syntax error.

28 Stack Abstract Data Type A stack of elements of type T is a finite sequence of elements of T, together with the following operations: 1. Create the stack, leaving it empty. 2. Test whether the stack is Empty. 3. Push a new entry onto the top of the stack, provided the stack is not full. 4. Pop the entry off the top of the stack, provided the stack is not empty. 5. Retrieve the Top entry from the stack, provided the stack is not empty.

29 Abstract Data Types An abstract data type allows us to think about algorithms without worrying about the details of the implementation. – We can change the implementation without changing the algorithm. It can clarify our thinking about the problem. – Using a stack is conceptually different than using a general array, even though a stack can be implemented using an array

30 Refinement When considering a programming problem it is helpful to use a refinement process. Abstract level – how do the data relate to each other, what operations are needed. Data structures level – what data structure and implementation should we use (e.g. we want to use a contiguous stack). Implementation level – exactly how will the methods of the stack be implemented. Application level – write the code that uses the data structure.


Download ppt "Introduction to Stacks Chapter 2. Objectives Introduce abstract data types. Discuss implementation types. – Static – Dynamic – Contiguous Introduce the."

Similar presentations


Ads by Google