0% found this document useful (0 votes)
87 views39 pages

L7a - Stack ADT

The document discusses stacks and their implementation using different data structures. It begins with an overview of stacks as a last-in, first-out data structure and common stack operations like push and pop. It then presents the stack abstract data type specification in C++. Several implementations of stacks are described, including using linked lists, STL vectors, and the STL stack container. Key considerations for choosing an implementation based on the underlying data structure's support for major stack operations are also covered.

Uploaded by

ales ferdinan
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)
87 views39 pages

L7a - Stack ADT

The document discusses stacks and their implementation using different data structures. It begins with an overview of stacks as a last-in, first-out data structure and common stack operations like push and pop. It then presents the stack abstract data type specification in C++. Several implementations of stacks are described, including using linked lists, STL vectors, and the STL stack container. Key considerations for choosing an implementation based on the underlying data structure's support for major stack operations are also covered.

Uploaded by

ales ferdinan
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/ 39

Lecture 7a

Stack ADT

A Last-In-First-Out Data Structure


Lecture Overview
 Stack
 Introduction
 Specification
 Implementations
 Linked List :O:O
 STL vector :O
 STL stack 
 Applications
 Bracket Matching
 Infix to Postfix Conversion

[ CS1020E AY1617S1 Lecture 7a ]


2
Stack: A Specialized List
 List ADT (Lecture 6) allows user to manipulate
(insert/retrieve/remove) item at any position within
the sequence of items
 There are cases where we only want to consider a
few specific positions only
 e.g. only the first/last position
 Can be considered as special cases of list
 Stack is one such example
 Only manipulation at the first (top) position is allowed
 Queue (Lecture 7b) is another example
 Only manipulation at the first (head) and last (tail)
position are allowed
[ CS1020E AY1617S1 Lecture 7a ]
3
What is a Stack
 Real life examples
 A stack of books, a stack of plates, etc.
 It is easier to add/remove item to/from the top of the
stack
 The latest item added is the first item you can get
out from the stack
 Known as Last In First Out (LIFO) order
 Major Operations
 Push: Place item on top of the stack
 Pop: Remove item from the top of the stack
 It is also common to provide
 Top: Take a look at the topmost item without removing it

[ CS1020E AY1617S1 Lecture 7a ]


4
Stack: Illustration
Top of stack
(accessible)

Push a new Pop a book


Bottom of book on top from top
stack A stack of
(inaccessible) four books
[ CS1020E AY1617S1 Lecture 7a ]
5
Stack ADT: C++ Specification
template <typename T>
class Stack { Stack ADT is a template class
public: (our previous List ADT in
Stack(); Lecture 6 can also be made as
template class)
bool isEmpty() const;
int size() const;
New C++ feature: const means
this function should not modify
void push(T newItem);
anything, i.e. a ‘getter’ function,
void top(T& stackTop) const;
your compiler will check it
void pop();

private:
// Implementation dependant
// See subsequent implementation slides
};

[ CS1020E AY1617S1 Lecture 7a ]


6
Stack ADT: Implementations
 Many ways to implement Stack ADT, we will see
 Linked List implementation
 Study the best way to make use of linked list
 Will go through this in detail
 STL vector implementation
 Make use of STL container vector
 Just a quick digress
 Or just use STL stack 

 Learn how to weight the pros and cons for each


implementation

[ CS1020E AY1617S1 Lecture 7a ]


7
Stack ADT: Design Consideration
 How to choose appropriate implementation?
 Concentrate on the major operations in ADT
 Match with data structures you have learned
 Pick one to be the internal (underlying) data structure of an
ADT
 Can the internal data structure support what you need?
 Is the internal data structure efficient in those operations?

 Internal data structure like array, linked list, etc.


are usually very flexible
 Make sure you use them in the best possible way

[ CS1020E AY1617S1 Lecture 7a ]


8
Stack ADT using Linked List
Stack ADT: Using Linked List
 Characteristics of singly linked list
 Efficient manipulation of 1st Node
 Has a head pointer directly pointing to it
 No need to traverse the list
 Manipulation of other locations is possible
 Need to first traverse the list, less efficient
 Hence, best way to use singly linked list
 Use 1st Node as the top of stack
 Question
 How would you use other variations of linked list?
 Will Doubly Linked List, Circular Linked List, or Tailed
Linked List help for Stack ADT implementation?
[ CS1020E AY1617S1 Lecture 7a ]
10
Stack ADT: Using Linked List (Illustration)
Internal of
Stack ADT Stack

top
grows Insert new
node at head of
IT … linked list

Push(IT)

Internal of
Stack ADT
top

Stack
shrinks Remove node
at head of
… linked list

Pop()
[ CS1020E AY1617S1 Lecture 7a ]
11
Stack ADT (Linked List): C++ Specification
template <typename T>
class Stack {
public: Need destructor as we
Stack(); allocate memory dynamically
~Stack();

bool isEmpty() const;


int size() const; Methods
from Slide 6.
void push(const T& newItem); No change.
void getTop(T& stackTop) const;
void pop();

private:
struct ListNode { Similar to Linked List
T item; implementation of List ADT
ListNode* next;
}; Yes, we reuse List ADT
from L6, but our L6 code is
ListNode* _head;
int _size; not on template class so
}; we violate the OOP rule 

StackLL.h
[ CS1020E AY1617S1 Lecture 7a ]
12
Implement Stack ADT (Linked List): 1/3
#include <string>
using namespace std;

template <typename T>


class StackLL {
public:
StackLL() : _size(0), _head(NULL) {}

~StackLL() {
while (!isEmpty()) Make use of own methods to
pop(); clear up the nodes
}

bool isEmpty() const {


return _size == 0; // try modify something here,
} // you'll get compile error

int size() const {


return _size;
}
StackLL.h, expanded

[ CS1020E AY1617S1 Lecture 7a ]


13
Implement Stack ADT (Linked List): 2/3
void push(T newItem) {
ListNode* newPtr = new ListNode;
newPtr->item = newItem; As we only insert at head
newPtr->next = _head; position. General insertion
_head = newPtr; code not needed. But yes, we
_size++; could have just use ListLL
} code from L6
void top(T& stackTop) const {
if (isEmpty())
throw string("Stack is empty on top()");
else {
New C++ feature:
stackTop = _head->item;
Exception handling.
}
We can throw RTE
}
StackLL.h, expanded

[ CS1020E AY1617S1 Lecture 7a ]


14
Implement Stack ADT (Linked List): 3/3
void pop() {
if (isEmpty())
throw string("Stack is empty on pop()");
else {
ListNode* cur;
cur = _head; As we only remove from head
_head = _head->next; position. General removal
delete cur; code not needed. But yes, we
cur = NULL; could have just use ListLL
_size--; code from L6
}
}

private:
struct ListNode {
T item;
ListNode* next;
};
ListNode* _head;
int _size;
};
StackLL.h, expanded
[ CS1020E AY1617S1 Lecture 7a ]
15
Stack ADT using STL vector

STL vector can be used to implement


Stack ADT too
Stack ADT: Using STL vector
 STL vector has the following capabilities
 Add/remove the last item
 push_back() and pop_back()
 Very efficient, later you will know that this is O(1)
 Use iterator to add/remove item from any location
 Not efficient
 Quite cumbersome (need to set up and move iterator)

 What Stack ADT needs


 Add/Remove from top of stack
 No manipulation of other locations
 Hence, to make the best use of STL vector
 Use the back of vector as the top of stack
[ CS1020E AY1617S1 Lecture 7a ]
17
Stack ADT: Using STL vector (Illustration)
Internal of IT size()-1
top
Stack ADT
Stack …
grows
1
Use
0 push_back(IT)

Push(IT)

Internal of size()-1
Stack ADT top
Stack …
shrinks
1
Use
0 pop_back()

Pop()
[ CS1020E AY1617S1 Lecture 7a ]
18
Stack ADT (STL vector): C++ Specification
#include <string>
We need STL vector.
#include <vector>
using namespace std;

template <typename T>


class StackV {
public:
StackV();
Methods from
bool isEmpty() const;
int size() const; Slide 6. No
change.
void push(T newItem);
void pop();
void top(T& stackTop) const;
private:
vector<T> _items;
};

The only private


declaration.

StackV.h
[ CS1020E AY1617S1 Lecture 7a ]
19
Implement Stack ADT (STL vector): 1/2
#include <string>
#include <vector>
using namespace std;

template <typename T>


class StackV { We use methods from
public: vector class to help us
StackV() {} // no need to do anything
bool isEmpty() const { return _items.empty(); }
int size() const { return _items.size(); }
void push(T newItem) { _items.push_back(newItem); }

void top(T& stackTop) const {


if (isEmpty())
throw string("Stack is empty on top()");
else
stackTop = _items.back();
}
StackV.h, expanded

[ CS1020E AY1617S1 Lecture 7a ]


20
Implement Stack ADT (STL vector): 2/2
void pop() {
if (isEmpty())
throw string("Stack is empty on pop()");
else
_items.pop_back();
}

private:
vector<T> _items;
};
StackV.h, expanded

[ CS1020E AY1617S1 Lecture 7a ]


21
STL stack

STL has a built-in stack ADT


Just use this whenever you need to use
Stack ADT
http://en.cppreference.com/w/cpp/container/stack
STL stack: Specification
template <typename T>
class stack {
public:
bool empty() const;
size_type size() const;
T& top();
void push(const T& t);
void pop();
};

 Very close to our own specification 


 One difference in top() method

[ CS1020E AY1617S1 Lecture 7a ]


23
STL stack: Example Usage
//#include "StackLL.h"
//#include "StackV.h" Output:
#include <stack>
#include <iostream> top: 3, size: 2
using namespace std;
After pop, top: 5, size: 1
int main() {
//StackLL<int> s; size: 0
//StackV<int> s;
stack<int> s;
int t;

s.push(5);
s.push(3);
//s.top(t);
t = s.top();
cout << "top: " << t << ", size: " << s.size() << endl;

s.pop();

//s.top(t);
t = s.top();
cout << "After pop, top: " << t << ", size: " << s.size() << endl;

s.pop(); // now the stack is empty


cout << "size: " << s.size() << endl;
//s.pop(); // will get RTE as stack is empty by now

return 0;
}
[ CS1020E AY1617S1 Lecture 7a ]
24
VisuAlgo
 http://visualgo.net/list?mode=Stack
 I use Single Linked List

[ CS1020E AY1617S1 Lecture 7a ]


25
Stack Applications
Stack Applications
 Many useful applications for stack
 Bracket Matching
 Calling a function
 Before the call, the state of computation is saved on the stack so that
we will know where to resume

 We may cover this 2 after we discuss recursion


 Tower of Hanoi
 Maze Exploration
 More “computer science” inclined examples
 Base-N number conversion
 Postfix evaluation
 Infix to postfix conversion
[ CS1020E AY1617S1 Lecture 7a ]
27
Stack Application 1

Bracket Matching
Bracket Matching: Description
 Mathematical expression can get quite
convoluted
 E.g. { [ x+2(i-4!)]^e+4π/5*(φ-7.28) ……

 We are interested in checking whether all


brackets are matched correctly,
i.e. ( with ), [ with ] and { with }

 Bracket matching is equally useful for


checking programming code
[ CS1020E AY1617S1 Lecture 7a ]
29
Bracket Matching: Pseudo-Code
1. Go through the input string character-by-character
 Non-bracket character
 Ignore
 Open bracket: { , [ or (
 Push into stack
 Close bracket: }, ] or )
 Pop from stack and check
 If stack is empty or the stack top bracket does not agree with
the closing bracket, complain and exit
 Else continue
2. If the stack is not empty after we read through the
whole string
 The input is wrong also
[ CS1020E AY1617S1 Lecture 7a ]
30
Bracket Matching: Implementation (1)
bool check_bracket(string input) {
stack<char> sc;
char current;
bool ok = true;

for (unsigned int pos = 0;


ok && pos < input.size(); pos++){
current = input[pos];
switch (current){
case '{':
sc.push('}'); //Question: Why are we pushing the
break; // closing bracket here??
case '[':
sc.push(']');
break;
case '(':
sc.push(')');
break;

[ CS1020E AY1617S1 Lecture 7a ]


31
Bracket Matching: Implementation (2)
case '}':
case ']':
case ')':
if (sc.empty()) //missing open bracket
ok = false;
else {
if (sc.top() == current)//matched!
sc.pop();
else //mismatched!
ok = false;
}
break;
}
}

if (sc.empty() && ok) // make sure no left over


return true;
else
return false;
}
[ CS1020E AY1617S1 Lecture 7a ]
32
Stack Application 2

Arithmetic Expression –
Evaluating Postfix Expression
Infix to Postfix Conversion
Application 2: Arithmetic Expression
 Terms
 Expression: a=b+c*d
 Operands: a, b, c, d
 Operators: =, +, –, *, /, %

 Precedence rules: Operators have priorities


over one another as indicated in a table (which
can be found in most books)
 Example: *, / have higher precedence over +, –.
 For operators at the same precedence (e.g. * and /),
we associate them from left to right

[ CS1020E AY1617S1 Lecture 7a ]


34
Application 2: Arithmetic Expression

Infix - operand1 operator operand2


Prefix - operator operand1 operand2
Postfix - operand1 operand2 operator

Ambiguous, need () Unique interpretation


or precedence rules postfix
(2+3)*4 2 3 + 4 *
infix

2+3*4

2+(3*4) 2 3 4 * +

[ CS1020E AY1617S1 Lecture 7a ]


35
Algorithm: Calculating Postfix Expression with Stack
Create an empty stack
for each item of the expression,
if it is an operand,
2 * (3 + 4) 2 3 4 + *
push it on the stack
if it is an operator,
pop arguments from stack; 2 s.push(2)
perform the operation; 3 s.push(3)
4 s.push(4)
push the result onto the stack +
Stack arg2 = s.pop ()
arg1 = s.pop ()
s.push (arg1 + arg2)
* arg2 = s.pop ()
arg1
arg1 = s.pop ()
32 s.push (arg1 * arg2)
4
arg2
3 7
47
2 14
[ CS1020E AY1617S1 Lecture 7a ]
36
Algorithm: Converting Infix to Postfix
String postfixExp = "";
for (each character ch in the infix expression) {
switch (ch) {
case operand: postfixExp = postfixExp + ch; break;
case '(': stack.push(ch); break;
case ')': while ( stack.peek() != '(' )
postfixExp = postfixExp + stack.pop();
stack.pop(); break; // remove '('
case operator:
while ( !stack.empty() && stack.peek() != '(' &&
precedence(ch) <= precedence(stack.peek()) )
postfixExp = postfixExp + stack.pop();
stack.push(ch); break;
} // end switch
} // end for
while ( !stack.empty() )
postfixExp = postfixExp + stack.pop();

[ CS1020E AY1617S1 Lecture 7a ]


37
Algorithm: Converting Infix to Postfix
ch Stack postfixExp
a a
– – a
Example: a – ( b + c * d ) / e
( –( a
b –( ab
+ –(+ ab
c –(+ abc
* –(+* abc
d –(+* abcd Move operators from stack to
) –(+ abcd* postfixExp until '('
–( abcd*+
– abcd*+
/ –/ abcd*+ Copy remaining operators
e –/ abcd*+e from stack to postfixExp
abcd*+e/–
[ CS1020E AY1617S1 Lecture 7a ]
38
Summary
Arithmetic Bracket
Applications
Expression Matching

Uses Uses

Stack ADT
Stack
pop() =STL stack
(Last In First Out)
push()
top()

Implements Implements

Implementations
Linked List STL vector

[ CS1020E AY1617S1 Lecture 7a ]


39

You might also like