30
Introduction to Stacks Chapter 2

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

Embed Size (px)

Citation preview

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

Introduction to Stacks

Chapter 2

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

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.

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

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)

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

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.

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

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

<stack>).• A stack would be useful in writing a program that reverses a list of

numbers.

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

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.

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

STL Stacks#include <stack>#include <iostream>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<double> numbers; // declares and initializes a stack of numberscout << "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;

}

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

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.

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

Stack Frames

• A stack frame is a representation of the contents of a stack at a given instant.

stack operation stack frames.push(‘A’);

s.push(‘B’);

s.pop();

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

Homework – Section 2.1 (page 56)

• Written– E1 (a, b, c, d) (written on paper) (2 pts each)

• Programming– E2 (email code) (5 pts)

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

Stack Header#include<iostream>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(); // constructorbool empty() const;/* Pre: None.

Post: If the Stack is empty, true is returned. Otherwise false is returned. */

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

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];

};

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

Enum Keyword

• The lineenum 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.

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

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.

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

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;}

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

Contiguous Stack ImplementationError_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;}

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

Contiguous Stack Implementationbool 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;}

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

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.

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

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)

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

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

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

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 operation stack 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.

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

RPN Programint 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));

}

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

RPN Calculatorchar get_command()/* Post: Returns a command (?, =, +, -, *, /, q) entered by the user */{

char command;bool waiting = true;cout << "Select command and press < Enter > :";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;

}

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

RPN Calculatorbool 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;

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

RPN Calculatorcase '+':

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;

}

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

Homework – Section 2.3 (page 69)

• Written– E1 (written on paper) (5 pts)

• Programming– P1 (nothing to turn in) – P2 (email code) (5 pts)

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

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.

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

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.

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

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

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

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.