Lecture05 Updated
Lecture05 Updated
Lecture #5
• Stacks
• Queues
2
Stacks
What’s the big picture?
A stack is a data structure that resembles
a stack of plates at a buffet.
Just like a stack of plates, the last
plate/value you add is at the top of the
stack, and thus the first to be removed.
10 8
10 8
10
Uses:
Use stacks to find
8 a path through a
10 10 maze, “undo” in a
word processor,
The last-added/first-removed aspect of and evaluate math
expressions.
stacks can help solve many hard problems!
4
Just like a stack of plates, the last item pushed onto the
top of a stack is the first item to be removed.
Stack operations:
• put something on top of the stack (PUSH)
• remove the top item (POP)
• look at the top item, without removing it
• check to see if the stack is empty
Note: You can only access the top item of the stack,
since the other items are covered.
6
Stacks
int main(void)
class Stack // stack of ints {
{ Stack is;
public:
Stack(); // c’tor is.push(10);
is.push(20);
void push(int i);
int pop(); ...
bool is_empty(void); }
int peek_top();
private:
... Answer:
}; How about an array
and a counter variable
to track where the
top of the stack is?
Question:
What type of data structure can we
use to implement our stack?
Implementing a Stack
7
return
int pop() { m_stack[1] is
So we
if (m_top == return 10
0) exit(-1); // underflow m_top 2
0
1
m_top -= 1;
return m_stack[m_top]; m_stack
} 0 5
...
1 7
10
2
private: ... …
int m_stack[SIZE];
10
7 99
int m_top; 5 a
}; 10
Stacks
9
Always Remember:
const int SIZE = 100; When we push, we:
class Stack
{ A. Store the new item in m_stack[m_top]
public: B. Post-increment our m_top variable
Stack() { m_top = 0; } (post means we do the increment after storing)
void push(int val) {
if (m_top >= SIZE) exit(-1); // overflow
m_stack[m_top] = val;
m_top += 1;
}
int pop() {
if (m_top == 0) exit(-1); // underflow
m_top -= 1;
return m_stack[m_top]; Always Remember:
}
When we pop, we:
... A. Pre-decrement our m_top variable
private: B. Return the item in m_stack[m_top]
int m_stack[SIZE]; (pre means we do the
int m_top; decrement before returning)
};
Stacks
10
Stack Challenge
Show the resulting stack after the following program runs:
#include <iostream>
#include <stack>
using namespace std;
int main()
{
stack<int> istack; // stack of ints
istack.push(6);
for (int i=0;i<2;i++)
{
int n = istack.top();
istack.pop();
istack.push(i);
istack.push(n*2);
}
}
12
Stack Challenge
Show the resulting stack after the following program runs:
#include <iostream>
#include <stack>
using namespace std;
int main()
{ i 0
1
stack<int> istack; // stack of ints
n
istack.push(6);
for (int i=0;i<2;i++) 24
{ 12
1
int n = istack.top();
6
0
istack.pop();
istack.push(i);
istack.push(n*2);
}
}
13
As we’ll
Postfix notation is another waysee, postfix
to write expressions
algebraic have–
expressions
here the operator follows
no the
suchoperands: AB+
ambiguity!
Infix Postfix
Here are some infix 15 + 6 15 6 +
If you’ve ever
expressions andused an9 HP
– 4 Is that9 (5+10)
4 - *3
calculator, you’ve used
their postfix
(15 + 6) * 5 15or
6 + 5 *
equivalents:
postfix notation!
7 * 6 + 5 5 +7(10
6 ** 53)+
To3 understand
+ (4 * 5) infix
3 4 5expressions,
* + the
computer has to be equipped with
Postfix expressions are easier forprecedence
a computer torules!
compute than
infix expressions, because they’re unambiguous.
Class Challenge
Given the following postfix expression: 6 8 2 / 3 * -
Show the contents of the stack *after* the 3 has been
processed by our postfix evaluation algorithm.
Reminder:
1. Start with the left-most token.
2. If the token is a number:
a. Push it onto the stack
3. If the token is an operator:
a. Pop the top value into a variable called v2, and the
second-to-top value into v1.
b. Apply operator to the two #s (e.g., v1 / v2)
c. Push the result of the operation on the stack
4. If there are more tokens, advance to the next token and go
back to step #2
5. After all tokens have been processed, the top # on the stack
is the answer!
19
0 1 2 3 4 5 6 7
Start 0
(1,1) 1
2
3
4 Finish
5 (6,6)
6 X
7
22
1
start ## ## # # It does this because each new
square to explore is added to
2 # # # the END of the queue…
3 # ## # So squares closer to the
4 # starting square are explored
5 # ## before squares further away.
6 # goal
7 This is why it’s called a
“breadth-first” search.
37
Queue Implementations
We can use an array and an integer to represent a queue:
queue 6
5 6
9 9 rear 02
3
1
0 1 2 3 4 5 0
• Every time you insert an item, place it in the rear slot
of
the array
• Every time and
you increment
dequeue anthe rear
item, count
move all of the items
forward in the array and decrement the rear count.
Queue Implementations
We can also use a linked list to represent a queue:
queue
X
6
5
0
6
9
1
9
2 3 4 5
#include <iostream>
#include <queue>
int main()
{
std::queue<int> iqueue; // queue of ints
Class Challenge
Given a circular queue of 6 elements, show the
queue’s contents, and the Head and Tail pointers
after the following operations are complete:
enqueue(5)
enqueue(10)
enqueue(12)
dequeue()
enqueue(7)
dequeue()
enqueue(9)
enqueue(12)
enqueue(13)
dequeue()