0% found this document useful (0 votes)
8 views42 pages

CSC312 -- Lecture 3a

This document provides an overview of stacks as an abstract data type (ADT), detailing core operations such as push, pop, and top, along with their applications and a case study on browser back navigation. It includes information on the Standard Template Library (STL) stack interface in C++, a simple array-based stack implementation, and various exercises to illustrate stack operations. The document serves as a lecture guide for students to gain foundational knowledge in data structures.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views42 pages

CSC312 -- Lecture 3a

This document provides an overview of stacks as an abstract data type (ADT), detailing core operations such as push, pop, and top, along with their applications and a case study on browser back navigation. It includes information on the Standard Template Library (STL) stack interface in C++, a simple array-based stack implementation, and various exercises to illustrate stack operations. The document serves as a lecture guide for students to gain foundational knowledge in data structures.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

Stacks

The CSC312 Team


Reference Textbook for this Topic
Title
Data Structures and Algorithms in C++, Second
Edition
John Wiley & Sons

Authors
Michael T. Goodrich, Roberto Tamassia, and David M. Mount.

2
Lecture Objective

▪ At the end of this lecture, students will gain a foundational understanding of


stacks as an abstract data type (ADT), focusing on core operations such as
push, pop, and top, and their applications. They will explore the STL
stack interface in C++, learning to implement stacks using arrays, and apply
these concepts in a practical case study.

3
Lecture Outline
▪ Introduction
▪ The Stack Abstract Data Type
▪ The Stack ADT Operations
▪ The STL Stack
▪ Stack Interface (using C++)
▪ A Simple Array-Based Stack Implementation
▪ Case Study Example
▪ Browser Back Navigation

4
Introduction

▪ A stack is a container of objects that are inserted


and removed according to the last-in first-out
(LIFO) principle.

▪ Objects can be inserted into a stack at any time, but


only the most recently inserted (that is, “last”) object
can be removed at any time.

5
Introduction

6
Introduction
▪ Stacks are a fundamental data structure. They are used in many
applications, including the following:
▪ Direct applications
▪ Page-visited history in a Web browser
▪ Undo sequence in a text editor
▪ Chain of method calls in the C++ run-time system
▪ Indirect applications
▪ Auxiliary data structure for algorithms
▪ Component of other data structures

7
The Stack Abstract Data Type
▪ Formally, a stack is an abstract data type (ADT) that supports the following operations:
Operation Description
push(𝑒) Insert element 𝑒 at the top of the stack.
pop() Remove the top element from the stack; an error occurs if the stack is
empty.
top() Return a reference to the top element on the stack, without removing
it; an error occurs if the stack is empty.
size() Return the number of elements in the stack.
empty() Return true if the stack is empty and false otherwise.

▪ Note: 𝑠𝑖𝑧𝑒() and 𝑒𝑚𝑝𝑡𝑦() are supporting member functions.


8
The Stack ADT Operations
▪ The following table shows a series of stack operations and their effects on an initially empty
stack of integers.
Operation Output Stack Contents
(Cont’d)
push(9) - (9)
push(5) - (5)
push(7) - (9,7)
push(3) - (5,3)
push(3) - (9,7,3)
pop() - (5)
push(5) - (9,7,3,5)
push(7) - (5,7)
size() 4 (9,7,3,5)
pop() - (5)
pop() - (9,7,3)
top() 5 (5)
push(8) - (9,3,7,8)
pop() - ()
pop() - (9,7,3)
pop() “error” ()
top() 3 (9,7,3)
top() “error” ()
empty() true () 9
The STL Stack

▪ The Standard Template Library provides an implementation of a stack.


▪ The underlying implementation is based on the STL vector class.
▪ In order to declare an object of type stack, it is necessary to first include the definition
file, which is called “stack”.
▪ As with the STL vector, the class stack is part of the std namespace, so it is necessary
either to use “std::stack” or to provide a “using” statement.

10
The STL Stack
▪ List the principal member functions. Let 𝒔 be declared to be an STL vector, and let 𝒆
denote a single object whose type is the same as the base type of the stack.
▪ For example, 𝒔 is a vector of integers, and 𝒆 is an integer.
Operation Description
size() Return the number of elements in the
stack.
#include <stack> empty() Return true if the stack is empty and
using std::stack; // make stack accessible false otherwise.
stack<int> myStack; // a stack of integers push(𝑒) Push e onto the top of the stack.
pop() Pop the element at the top of the stack.
top() Return a reference to the element at
the top of the stack.
11
Stack Interface (using C++ )
▪ This entails specifying the Application Programming Interface (API), or
simply interface,
▪ which describes the names of the public members that the ADT must support and how
they are to be declared and used.
▪ The C++ programming language does not provide a simple method for
defining interfaces.
▪ The informal interface for the stack ADT is given in Code Fragment (See
Next Slide)
12
template <typename E> //The element type is indicated by E
class Stack { // an interface for a stack
public:
int size() const; // number of items in stack
bool empty() const; // is the stack empty?
const E& top() const throw(StackEmpty); // the top element
void push(const E& 𝑒); // push 𝑒 onto the stack
void pop() throw(StackEmpty); // remove the top element
};

// Exception thrown on performing top or pop of an empty stack.


// Define a custom exception class StackEmpty that inherits from RuntimeException
class StackEmpty : public RuntimeException {
public:
// Constructor for StackEmpty class, passes the error message to the base class RuntimeException
StackEmpty(const string& err) : RuntimeException(err) {}
};
An informal Stack interface 13
Stack Interface (using C++ )
▪ Based on the C++ Stack Interface (previous interface)
▪ The member functions size, empty, and top are all declared to be const, which
informs the compiler that they do not alter the contents of the stack.
▪ top returns a constant reference to the top of the stack, which means that its value may
be read but not written.
▪ pop does not return the element that was popped.
▪ If the user wants to know this value, it is necessary to perform a top operation first, and save
the value.
▪ push takes a constant reference to an object of type E as its argument.
14
A Simple Array-Based Stack Implementation

▪ A simple way of implementing the Stack ADT uses an array.


▪ We add elements from left to right.
▪ A variable keeps track of the index of the top element.

15
A Simple Array-Based Stack Implementation
▪ This is simple way of implementing the
Stack ADT
▪ Elements are added from left to right
▪ A variable keeps track of the index of the
top element
▪ The array storing the stack elements may
become full
▪ A push operation will then throw a
StackFull exception

16
A C++ Implementation of a Array-based Stack
template <typename E> // member data
// default stack capacity private:
class ArrayStack { // array of stack elements
enum { DEF_CAPACITY = 100 }; E* S;
public: // stack capacity
// constructor from capacity int capacity;
ArrayStack(int cap = DEF_CAPACITY);
// index of the top of the stack
// number of items in the stack
int t;
int size() const;
};
// is the stack empty?
bool empty() const;
// get the top element
const E& top() const throw(StackEmpty);
// push element onto stack
void push(const E& e) throw(StackFull);
// pop the stack
void pop() throw(StackEmpty);
17
A Simple Array-Based Stack Implementation
Limitations

▪ The maximum size of the stack must be defined a priori and cannot be
changed.
▪ Trying to push a new element into a full stack causes an
implementation-specific exception.

18
A C++ Implementation of a Array-based Stack
Explanation (1 of 2)

▪ A constructor is provided, that is given the desired capacity of the stack as


its only argument.
▪ If no argument is given, the default value given by DEF_CAPACITY is used.
▪ Enumeration is used to define this default capacity value.
▪ This is the simplest way of defining symbolic integer constants within a C++ class.

▪ The class is templated with the element type, denoted by E.


▪ The stack’s storage, denoted S, is a dynamically allocated array of type E,
that is, a pointer to E.
19
A C++ Implementation of a Array-based Stack
Explanation (2 of 2)
▪ The constructor allocates the array storage, whose size is set to the
default capacity.
▪ The members 𝑐𝑎𝑝𝑎𝑐𝑖𝑡𝑦 and 𝑡 are also set to their initial values.
▪ Note the following about implementing the member functions top,
pop and push
▪ top and pop first check that the stack is not empty, and otherwise, they throw
an exception.
▪ Similarly, push first checks that the stack is not full, and otherwise, it throws an
exception.
20
A Simple Array-Based Stack Implementation
Example One

▪ This is an example of the use of the ArrayStack class.


▪ To demonstrate the flexibility of its implementation, two stacks of different
base types are used.
▪ The instance A is a stack of integers of the default capacity (100).
▪ The instance B is a stack of character strings of capacity 10.

21
A Simple Array-Based Stack Implementation
Example One
ArrayStack<int> A; // A = [ ], size = 0 * indicates top
A.push(7); // A = [7*], size = 1
A.push(13); // A = [7, 13*], size = 2
cout << A.top() << endl; A.pop(); // A = [7*], outputs: 13
A.push(9); // A = [7, 9*], size = 2
cout << A.top() << endl; // A = [7, 9*], outputs: 9
cout << A.top() << endl; A.pop(); // A = [7*], outputs: 9
ArrayStack<string> B(10); // B = [ ], size = 0
B.push("Bob"); // B = [Bob*], size = 1
B.push("Alice"); // B = [Bob, Alice*], size = 2
cout << B.top() << endl; B.pop(); // B = [Bob*], outputs: Alice
B.push("Eve"); // B = [Bob, Eve*], size = 2
22
A Simple Array-Based Stack Implementation:
Example one: Explanation
▪ In example one, we chose the default capacity value 𝑁 = 100 more or less
arbitrarily
▪ Although the user can set the capacity in the constructor.
▪ An application may actually need much less space than the given initial size,
and this would be wasteful of memory.
▪ Alternatively, an application may need more space than this, in which case our
stack implementation might “crash” if too many elements are pushed onto the
stack.
▪ Fortunately, there are other implementations (e.g. STL stack class) that do not
impose an arbitrary size limitation.
▪ It offers the advantage that it is automatically expanded when the stack
overflows its current storage limits.
23
Class Exercise 1

▪ Describe the output of the following series of stack operations:


push(5), push(3), pop(), push(2), push(8), pop(), pop(), push(9), push(1),
pop(), push(7), push(6), pop(), pop(), push(4), pop(), pop(), size().

24
Class Exercise 1: Solution
Operation Output Stack Contents (Cont’d)
push(5) - (5) push(7) - (5,9,7)
push(3) - (5,3) push(6) - (5,9,7,6)
pop() - (5) pop() - (5,9,7)
push(2) - (5,2) pop() - (5,9)
push(8) - (5,2,8) push(4) - (5,9,4)
pop() - (5,2) pop() - (5,9)
pop() - (5) pop() - (5)
push(9) - (5,9) Size() 1 (5)
push(1) - (5,9,1)
pop() - (5,9)
25
Class Exercise 2
▪ Consider a stack and the following sequence of 20 operations.
Determine the output of each operation and the final state of the
stack.
pop(), push(A), push(B), push(C), size(), top(), pop(), push(D), top(),
pop(), empty(), push(E), push(F), size(), pop(), top(), push(G), push(H),
size(), empty()

26
Class Exercise 2: Solution
(Cont’d)
Operation Output Stack Contents
empty() False (A,B)
pop() “error” ()
push(E) - (A,B,E)
push(A) - (A)
push(F) - (A,B,E,F)
push(B) - (A,B)
size() 4 (A,B,E,F)
push(C) - (A,B,C)
pop() - (A,B,E)
size() 3 (A,B,C)
top() E (A,B,E)
top() C (A,B,C)
push(G) - (A,B,E,G)
pop() - (A,B)
Push(H) - (A,B,E,G,H)
push(D) - (A,B,D)
size() 5 (A,B,E,G,H)
top() D (A,B,D)
empty() False (A,B,E,G,H)
pop() - (A,B)
27
Class Exercise 3
▪ Consider the following sequence of operations on an ArrayStack of type string with a maximum
size of 10. Provide the corresponding output for each statement in the form of a comment.
ArrayStack<string> B(10);
B.push("David");
B.push("Mary");
cout << B.top() << endl; B.pop();
B.push("Moses");
B.push("Ruth");
cout << B.top() << endl; B.pop();
B.push("Esther");
B.push("Joshua");
cout << B.top() << endl;
B.pop();
B.push("Naomi");
cout << B.top() << endl; B.pop();
28
Class Exercise 3: Solution
ArrayStack<string> B(10); // B = [ ], size = 0
B.push("David"); // B = [David*], size = 1
B.push("Mary"); // B = [David, Mary*], size = 2
cout << B.top() << endl; B.pop(); // B = [David*], outputs: Mary
B.push("Moses"); // B = [David, Moses*], size = 2
B.push("Ruth"); // B = [David, Moses, Ruth*], size = 3
cout << B.top() << endl; B.pop(); // B = [David, Moses*], outputs: Ruth
B.push("Esther"); // B = [David, Moses, Esther*], size = 3
B.push("Joshua"); // B = [David, Moses, Esther, Joshua*], size = 4
cout << B.top() << endl; // B = [David, Moses, Esther, Joshua*], outputs: Joshua
B.pop(); // B = [David, Moses, Esther*], size = 3
B.push("Naomi"); // B = [David, Moses, Esther, Naomi*], size = 4
cout << B.top() << endl; B.pop(); // B = [David, Moses, Esther*], outputs: Naomi

29
Case Study Example:
Browser Back Navigation
▪ When using a web browser, users often navigate through multiple web pages.
▪ Browsers implement a "Back" button that allows users to return to previously
visited pages in the reverse order they were visited.
▪ This functionality is an excellent example of a stack data structure.
▪ In this case, each page a user visits is "pushed" onto a stack, and
▪ each time the user presses the "Back" button, the current page is "popped" from the
stack, revealing the previous page.
▪ This Last-In, First-Out (LIFO) order makes stacks an ideal choice for implementing
browser back navigation.
30
Case Study Example:
Browser Back Navigation
Push Operation Pop Operation Empty Operation Top Operation
(Navigating to a New (Displaying the
Page) (Back Button) (Check First Page)
Current Page)

When a user visits a When the "Back" If the stack is empty The current page can
new page, the button is pressed, the when the user presses be accessed by looking
current page (if browser removes "Back," it means there at the "top" of the
any) is stored on (pops) the most are no previous pages stack.
the stack. recent page from the to return to.
stack

The new page is


The previous
then displayed.
page is then
displayed.

31
Case Study Example:
Browser Back Navigation: push operation
▪ Here is the sequence of stack operations when the user navigates from the homepage to
page 1, then to page 2, and finally to page 3.

32
Case Study Example:
Browser Back Navigation: pop operation
▪ After the push operations, the final state of the stack is (homepage, page1, page2,
page3). Therefore, if the user carries out the back navigation action, we have:

33
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main() {
stack<string> backStack; // Stack to hold previously visited pages
string currentPage = "Homepage"; // Starting page

cout << "Current page: " << currentPage << endl;

// Navigating to new pages


backStack.push(currentPage); // Push current page to back stack
currentPage = "Page1"; // Visit new page
cout << "Navigated to: " << currentPage << endl;

C++ Implementation of the Browser Back Navigation 34


backStack.push(currentPage); // Push current page to back stack
currentPage = "Page2"; // Visit new page
cout << "Navigated to: " << currentPage << endl;

backStack.push(currentPage); // Push current page to back stack


currentPage = "Page3"; // Visit new page
cout << "Navigated to: " << currentPage << endl;

// Implementing the "Back" button functionality


cout << "\nPressing 'Back' button:\n";

if (!backStack.empty()) {
currentPage = backStack.top(); // Go back to the previous page
backStack.pop(); // Remove the top page from the stack
cout << "Back to: " << currentPage << endl;
} else {
cout << "No previous pages to go back to.\n";
}
C++ Implementation of the Browser Back Navigation (Cont’d) 35
if (!backStack.empty()) {
currentPage = backStack.top(); // Go back to the previous page
backStack.pop(); // Remove the top page from the stack
cout << "Back to: " << currentPage << endl;
} else {
cout << "No previous pages to go back to.\n";
IMPLEMENTATION OUTPUT:
} Current page: Homepage
Navigated to: Page1
return 0; Navigated to: Page2
} Navigated to: Page3

Pressing 'Back' button:


Back to: Page2
Back to: Page1

C++ Implementation of the Browser Back Navigation (Cont’d) 36


Lecture Summary
▪ A stack is a linear data structure that follows the Last In, First Out (LIFO)
principle,
▪ meaning the last element added is the first one to be removed.
▪ It is often compared to a stack of plates, where the plate on top is the one that is
removed first.
▪ Its operations include: push(), pop(), top(), size(), empty()
▪ In an array-based stack, a fixed-size array is used to store the elements.
▪ The array has a pointer or an index called top that tracks the position of the most recent
element.

37
EXERCISES
Exercise 1
▪ You are tasked with developing a library application that manages the books currently being read by
users. The library staff needs a system to keep track of the books that users have checked out. When a
user checks out a book, it is added to the collection of currently checked-out books. The most recently
checked-out book should be the first one that is returned. Write a C++ program that fulfills the
following requirements:
▪ Add a new book to the data structure when it is checked out (push operation).
▪ Each book should have a title and a unique ISBN number.
▪ Remove the book that is currently at the top of the data structure when it is returned (pop
operation).
▪ Display the details of the book currently at the top of the stack.
▪ Show the total number of books currently checked out.
▪ Provide a method to check if there are any books currently checked out (i.e., if the data structure
is empty)
39
Exercise 2

▪ Implement an ArrayStack class in C++ that simulates a stack using arrays.


Your stack should support basic stack operations:
▪ push (to add an element to the top),
▪ pop (to remove the top element), and
▪ top (to view the top element without removing it).
▪ Additionally, implement the following functions:
▪ isEmpty function to check if the stack is empty and
▪ isFull function to check if the stack has reached its maximum capacity.

40
Exercise 3
▪ You are developing a simple customer service application for a bank. In this system,
customer requests are processed on a "Last In, First Out" (LIFO) basis. This is because
some urgent requests may override the older requests temporarily. Each customer request
is added to a stack, and the bank staff will handle the most recent requests first, removing
them as they are resolved. Write a C++ program that simulates this functionality using an
array-based stack.Your program should allow the following operations:
▪ Add a new request
▪ Resolve the most recent request
▪ Check the most recent request without removing it
▪ Check if the stack is empty
▪ Check if the stack is full
41
Exercise 4

▪ Identify and explain five (5) application areas where the stack data
structure is used. For each application area, provide a relevant
example or scenario to illustrate its use.

▪ Discuss the benefits and drawbacks of using the stack data structure.

42

You might also like