1 / 85

# Stacks and Queues - PowerPoint PPT Presentation

Stacks and Queues. Andy Wang Data Structures, Algorithms, and Generic Programming. Abstract Data Type. A collection of data A set of operations on the data or subsets of the data A set of axioms , or rules of behavior governing the interaction of operators

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

## PowerPoint Slideshow about 'Stacks and Queues' - akamu

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

### Stacks and Queues

Andy Wang

Data Structures, Algorithms, and Generic Programming

• A collection of data

• A set of operations on the data or subsets of the data

• A set of axioms, or rules of behavior governing the interaction of operators

• Examples: stack, queue, list, vector, deque, priority queue, table (map), associative array, set, graph, digraph

• Collections:

• Elements of some proper type T

• Operations:

• void push(T t)

• void pop()

• T top()

• bool empty()

• unsigned int size()

• constructor and destructor

• Axioms (for any stack S)

• S.size, S.empty(), and S.push(t) are always defined

• S.pop() and S.top() are defined iff S.empty() is false

• S.empty(), S.size(), S.top() do not change S

• S.empty() is true iff S.size() == 0

• S.push(t) followed by S.pop() leaves S unchanged

• Axioms (for any stack S)

• After S.push(t), S.top() returns t

• S.push(t) increases S.size() by 1

• S.pop() decreases S.size() by 1

• Empty stack S

• S.empty() is true

• S.top() not defined

• S.size() == 0

food chain stack

• S.push(“mosquito”)

• S.empty() is false

• S.top() == “mosquito”

• S.size() == 1

food chain stack

• S.push(“fish”)

• S.empty() is false

• S.top() == “fish”

• S.size() == 2

food chain stack

• S.push(“raccoon”)

• S.empty() is false

• S.top() == “raccoon”

• S.size() == 3

food chain stack

• S.pop()

• S.empty() is false

• S.top() == “fish”

• S.size() == 2

food chain stack

• If (S.size() == n) is followed by k push operations, then S.size() == n + k

• If (S.size() == n) is followed by k pop operations, then S.size == n – k (k <= n)

• The last element of S pushed onto S is the top of S

• S.pop() removes the last element of S pushed onto S

• Depth first search / backtracking

• Evaluating postfix expressions

• Converting infix to postfix

• Function calls (runtime stack)

• Recursion

• Collection

• Elements of some proper type T

• Operations

• void push(T t)

• void pop()

• T front()

• bool empty()

• unsigned int size()

• Constructors and destructors

• Axioms (for any Queue Q)

• Q.size(), Q.empty(), Q.push(t) are always defined

• Q.pop() and Q.front() are defined iff Q.empty() is false

• Q.empty(), Q.size(), Q.front() do not change Q

• Q.empty() is true iff Q.size() == 0

• Suppose Q.size() == n, and the next element pushed onto Q is t; then, after n elements have been popped from Q, t = Q.front()

• Axioms (for any Queue Q)

• Q.push(t) increases Q.size() by 1

• Q.pop() decreases Q.size() by 1

• If t = Q.front() then Q.pop() removes t from Q

• Empty Q

back

Queue Model—FIFO

• Q.Push(“ant”)

back

Queue Model—FIFO

• Q.Push(“bee”)

back

Queue Model—FIFO

• Q.Push(“cat”)

back

Queue Model—FIFO

• Q.Push(“dog”)

back

Queue Model—FIFO

• Q.Pop()

back

Queue Model—FIFO

• Q.Pop()

back

Queue Model—FIFO

• Q.Push(“eel”)

• Q.Pop()

• Q.Pop()

• If (Q.size() == n) is followed by k push operations, then Q.size() == n + k

• If (Q.size() == n) is followed by k pop operations, then Q.size() == n – k (k <= n)

• The first element pushed onto Q is the the front of Q

• Q.pop() removes the front element of Q

• Buffers

• Simulations

Discover a path from start to goal

Solution

Go deep

If there is an unvisited neighbor, go there

Backtrack

Retreat along the path to find an unvisited neighbor

Outcome

If there is a path from start to goal, DFS finds one such path

Depth First Search—Backtracking

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Stack

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

Push

• Stack

1

start

2

3

4

5

6

7

8

9

10

11

12

Push

goal

Push

• Stack

1

start

2

3

4

5

6

7

8

Push

9

10

11

12

Push

goal

Push

• Stack

1

start

2

3

4

Push

5

6

7

8

Push

9

10

11

12

Push

goal

Push

• Stack

1

start

Push

2

3

4

Push

5

6

7

8

Push

9

10

11

12

Push

goal

Push

• Stack

1

start

Pop

2

3

4

Push

5

6

7

8

Push

9

10

11

12

Push

goal

Push

• Stack

1

start

2

3

4

Pop

5

6

7

8

Push

9

10

11

12

Push

goal

Push

• Stack

1

start

2

3

4

5

6

7

8

Pop

9

10

11

12

Push

goal

Push

• Stack

1

start

2

3

4

5

6

7

8

9

10

11

12

Pop

goal

Push

• Stack

1

start

2

3

4

5

6

7

8

9

10

11

12

Push

goal

Push

• Stack

1

start

2

3

4

5

6

7

8

Push

9

10

11

12

Push

goal

Push

• Stack

1

start

2

3

4

Push

5

6

7

8

Push

9

10

11

12

Push

goal

Push

DFS {

stack<location> S;

// mark the start location as visited

S.push(start);

while (S is not empty) {

t = S.top();

if (t == goal) Success(S);

if (// t has unvisited neighbors) {

// choose an unvisited neighbor

// mark n visited;

S.push(n);

} else {

BackTrack(S);

}

}

Failure(S);

}

BackTrack(S) {

while (!S.empty() && S.top() has no unvisited neighbors) {

S.pop();

}

}

Success(S) {

// print success

while (!S.empty()) {

output(S.top());

S.pop();

}

}

Failure(S) {

// print failure

while (!S.empty()) {

S.pop();

}

}

• Problem

• Find a shortest path from start to goal

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Push

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Pop

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Push

Push

Push

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Pop

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Push

Push

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Pop

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Push

Push

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Pop

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Pop

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Pop

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Push

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Pop

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

• Queue

Push

1

start

2

3

4

5

6

7

8

9

10

11

12

goal

BFS {

queue<location> Q;

// mark the start location as visited

Q.push(start);

while (Q is not empty) {

t = Q.front();

for (// each unvisited neighbor n) {

Q.push(n);

if (n == goal) Success(S);

}

Q.pop();

}

Failure(Q);

}

• Postfix expressions: operands precede operator

• Tokens: atomics of expressions, either operator or operand

• Example:

• z = 25 + x*(y – 5)

• Tokens: z, =, 25, +, x, *, (, y, -, 5, )

• Evaluation algorithm:

• Use stack of tokens

• Repeat

• If operand, push onto stack

• If operator

• pop operands off stack

• evaluate operator on operands

• push result onto stack

• Most CPUs have hardware support for this algorithm

• Translation from infix to postfix also uses a stack (software)

• Original expression: 1 + (2 + 3) * 4 + 5

• Evaluate: 1 2 3 + 4 * + 5 +

• Input: 1 2 3 + 4 * + 5 +

• Push(1)

• Input: 2 3 + 4 * + 5 +

• Push(2)

• Input: 3 + 4 * + 5 +

• Push(3)

• Input: + 4 * + 5 +

• Pop() == 3

• Pop() == 2

• Input: + 4 * + 5 +

• Push(2 + 3)

• Input: 4 * + 5 +

• Push(4)

• Input: * + 5 +

• Pop() == 4

• Pop() == 5

• Input: * + 5 +

• Push(5 * 4)

• Input: + 5 +

• Pop() == 20

• Pop() == 1

• Input: + 5 +

• Push(1 + 20)

• Input: 5 +

• Push(5)

• Input: +

• Pop() == 21

• Pop() == 5

• Input: +

• Push(21 + 5)

• Input:

• Pop() == 26

Evaluate(postfix expression) {

// use stack of tokens;

while(// expression is not empty) {

t = next token;

if (t is operand) {

// push onto stack

} else {

// pop operands for t off stack

// evaluate t on these operands

// push result onto stack

}

}

}

• Runtime environment

• Static

• Executable code

• Global variables

• Stack

• Push for each function call

• Pop for each function return

• Heap

• Dynamic new and delete

heap

stack

static

program memory

• Order 1: function calls itself

• Order 2: f() calls g(), and g() calls f()

• Facilitated by stack

• Adapts the public interface of another class

• Adaptee: the class being used

• Adaptor: the new class being defined

• Uses protected object of the adaptee type

• Stack and Queue implemented via adaptor classes

• Stack

• PushBack()

• PopBack()

• Back()

• Empty()

• Size()

• Can use TDeque, TList, TVector

• Queue

• PushBack()

• PopFront()

• Front()

• Empty()

• Size()

• Can use TDeque, TList

template <typename T, class Container>

class CStack {

protected:

Container c;

public:

typedef T value_type;

void Push(const value_type& x) { c.PushBack(x); }

void Pop() { c.PopBack(); }

value_type Top() const { return c.Back(); }

int Empty() const { return c.Empty(); }

unsigned int Size() const { return c.Size(); }

void Clear() { c.Clear(); }

void Display(ostream& os, char ofc) const;

};

template <typename T, class Container>

void CStack<T, Container>::Display(std::ostream& os, char ofc) const {

typename Container::Iterator I;

if (ofc == ‘\0’) {

for (I = c.Begin(); I != c.End(); ++I) {

os << *I;

}

} else {

for (I = c.Begin(); I != c.End(); ++I) {

os << *I << ofc;

}

}

}

template <typename T, class Container>

std::ostream& operator<<(std::ostream& os, const CStack<T, Container>& s) {

s.Display(os);

return os;

}

• CStack<float, TList<float> > floatStack;

• CStack<int, TDeque<int> > intStack;

template <typename T, class Container>

class CQueue {

protected:

Container c;

public:

typedef T value_type;

void Push(const value_type& x) { c.PushBack(x); }

void Pop() { c.PopFront(); }

value_type Front() const { return c.Front(); }

int Empty() const { return c.Empty(); }

unsigned int Size() const { return c.Size(); }

void Clear() { c.Clear(); }

void Display(ostream& os, char ofc) const;

};

template <typename T, class Container>

void CQueue<T, Container>::Display(std::ostream& os, char ofc) const {

typename Container::Iterator I;

if (ofc == ‘\0’) {

for (I = c.Begin(); I != c.End(); ++I) {

os << *I;

}

} else {

for (I = c.Begin(); I != c.End(); ++I) {

os << *I << ofc;

}

}

}

template <typename T, class Container>

std::ostream& operator<<(std::ostream& os, const CQueue<T, Container>& s) {

s.Display(os);

return os;

}

• Functionality Testing

• fcstack.cpp

• fcqueue.cpp

• Performance Testing

• qrace.cpp

• srace.cpp

• dragstrp.h

• timer.h

• datetime.h

• xran.h