Stack Implementations Tiziana Ligorio 1 Todays Plan Stack - - PowerPoint PPT Presentation

stack implementations
SMART_READER_LITE
LIVE PREVIEW

Stack Implementations Tiziana Ligorio 1 Todays Plan Stack - - PowerPoint PPT Presentation

Stack Implementations Tiziana Ligorio 1 Todays Plan Stack Implementations: Array Vector Linked Chain 2 Stack ADT #ifndef STACK_H_ #define STACK_H_ template<<typename ItemType> class


slide-1
SLIDE 1

Stack Implementations

Tiziana Ligorio

1

slide-2
SLIDE 2

Today’s Plan

Stack Implementations:
 Array
 Vector
 Linked Chain

2

slide-3
SLIDE 3

Stack ADT

#ifndef STACK_H_
 #define STACK_H_
 
 template<<typename ItemType>
 class Stack 
 {
 
 public:
 Stack();
 void push(const ItemType& new_entry); //adds an element to top of stack
 void pop(); // removes element from top of stack
 ItemType top() const; // returns a copy of element at top of stack
 int size() const; // returns the number of elements in the stack
 bool isEmpty() const;//returns true if no elements on stack, else false 
 
 private:
 //implementation details here }; //end Stack
 
 #include "Stack.cpp"
 #endif // STACK_H_`

3

slide-4
SLIDE 4

ADT vs Data Structure

ADT is the logical/abstract description of the organization and operations on the data Data Structure is the representation/implementation of the ADT We may have multiple implementations of the same ADT


  • 1 ADT

  • Multiple Data Structures

To complicate matters, a data structure may be implemented using other data structures


  • stack implemented using vector

  • priority queue implemented using heap (more on this later)

If main() instantiates a stack, it is using a stack data structure, no matter which implementation we choose

4

slide-5
SLIDE 5

Choose a Data Structure

Array? Vector? Linked chain?

5

slide-6
SLIDE 6

Choose a Data Structure

Inserting and removing from same end (LIFO) Goal: minimize work - Ideally O(1) What would you suggest?

6

slide-7
SLIDE 7

Array

7

1 2 3 4 5

Where is the top

  • f the stack?

items_

slide-8
SLIDE 8

Array

8

1 2 3 4 5

Top of the stack: items_[item_count_] item_count_ = 0 max_items_ = 6

items_

slide-9
SLIDE 9

Array

9

O

1 2 3 4 5

Top of the stack: items_[item_count_]

items_

push(‘O’) item_count_ = 1 max_items_ = 6

slide-10
SLIDE 10

Array

10

O Z

1 2 3 4 5

Top of the stack: items_[item_count_]

items_

push(‘Z’) item_count_ = 2 max_items_ = 6

slide-11
SLIDE 11

Array

11

O Z B

1 2 3 4 5

Top of the stack: items_[item_count_]

items_

push(‘B’) item_count_ = 3 max_items_ = 6

slide-12
SLIDE 12

Array

12

O Z

1 2 3 4 5

Top of the stack: items_[item_count_]

items_

pop() item_count_ = 2 max_items_ = 6 Pops items_[item_count_ -1]

slide-13
SLIDE 13

Array Analysis

1 assignment + 1 increment/decrement = O(1) size : O(1)
 isEmpty: O(1)
 push: O(1)
 pop : O(1)
 top : O(1) GREAT!!!!

13

slide-14
SLIDE 14

Array Analysis

1 assignment + 1 increment/decrement = O(1) size : O(1)
 isEmpty: O(1)
 push: O(1)
 pop : O(1)
 top : O(1) GREAT???

14

slide-15
SLIDE 15

Array

15

O Z B Y L P

1 2 3 4 5

Top of the stack: items_[item_count_]

items_

push(’T’) item_count_ = 6 max_items_ = 6 Sorry Stack is Full!!!

slide-16
SLIDE 16

Vector

std::vector<T> some_vector; So what is a vector really?

16

slide-17
SLIDE 17

Vector

std::vector<T> some_vector; So what is a vector really?

17

2

buffer_ = len_ = capacity_ = 5

Vector (simplified)

O Z

1 2 3 4

Push and pop same as with arrays

slide-18
SLIDE 18

Vector

std::vector<T> some_vector; So what is a vector really?

18

buffer_ = len_ = 5 capacity_ = 5

Vector (simplified)

O Z B Y L

1 2 3 4

Stack is Full?

slide-19
SLIDE 19

Vector

std::vector<T> some_vector; So what is a vector really?

19

buffer_ = len_ = 5 capacity_ = ?

Vector (simplified)

O Z B Y L

1 2 3 4

No, I’ll Grow!!! O Z B Y L

1 2 3 4 5 6 . . .

slide-20
SLIDE 20

Lecture Activity

How much should it grow? Write a short paragraph arguing the pros and cons of growing by the amount you propose

20

slide-21
SLIDE 21

Vector Analysis

1 assignment + 1 increment/decrement = O(1) size : O(1)
 isEmpty: O(1)
 push: O(1)
 pop : O(1)
 top : O(1) GREAT!!!!

21

slide-22
SLIDE 22

Vector Analysis

1 assignment + 1 increment/decrement = O(1) size : O(1)
 isEmpty: O(1)
 push: O(1)
 pop : O(1)
 top : O(1) GREAT???

22

Except when stack is full must:


  • allocate new array

  • copy elements in new array

  • delete old array
slide-23
SLIDE 23

Vector Analysis

1 assignment + 1 increment/decrement = O(1) size : O(1)
 isEmpty: O(1)
 push: O(1)
 pop : O(1)
 top : O(1) GREAT???

23

Except when stack is full must:


  • allocate new array O(1)

  • copy elements in new array O(n)

  • delete old array O(1)
slide-24
SLIDE 24

How should Vector grow?

Sometimes 1 “step” Sometimes n “steps” Consider behavior over several pushes

24

slide-25
SLIDE 25

Vector Growth: a naive approach

std::vector<T> some_vector; So what is a vector really?

25

buffer_ = len_ = 5 capacity_ = 6

Vector (simplified)

O Z B Y L

1 2 3 4

I’ll Grow!!! I will add space for the item to be added O Z B Y L

1 2 3 4 5

slide-26
SLIDE 26

Vector Growth: a naive approach

If vector grows by 1 each time, every push costs n “steps” Cost of pushes:
 1 + 2 + 3 + 4 + 5 + . . . + n 
 = n (n+1)/2 


26

slide-27
SLIDE 27

Vector Growth: a naive approach

If vector grows by 1 each time, every push costs n “steps” Cost of n pushes:
 1 + 2 + 3 + 4 + 5 + . . . + n 
 = n (n+1)/2 
 = n2 /2 + n / 2 O(n2)

27

slide-28
SLIDE 28

Vector Growth: a better approach

std::vector<T> some_vector; So what is a vector really?

28

buffer_ = len_ = 5 capacity_ = 7

Vector (simplified)

O Z B Y L

1 2 3 4

I’ll Grow!!! I will add two more slots! O Z B Y L

1 2 3 4 5 6

slide-29
SLIDE 29

Vector Growth: a better approach

If vector grows by 2 each time, Let a “hard push” be one where the whole vector needs to be copied When vector is not copied we have an “easy push” Now half our pushes will be easy (1 step) and half will be hard (n steps) So if reconsider the work over several pushes?

29

slide-30
SLIDE 30

Analysis visualization adapted from Keith Schwarz

30

slide-31
SLIDE 31

Vector Growth: a better approach

31

Easy push Easy push Easy push Hard push Hard push Hard push Hard push Easy push

slide-32
SLIDE 32

Vector Growth: a better approach

32

Work Saved

Easy push Easy push Easy push Hard push Hard push Hard push Hard push

By simply adding one extra “slot” we roughly cut down the work by half on average (over several pushes)

Easy push

slide-33
SLIDE 33

Vector Growth: a better approach

33

Easy push Easy push Easy push Hard push Hard push Hard push Hard push

Let’s look at it a different way: what happens if I spread the work over time?

Easy push

slide-34
SLIDE 34

Vector Growth: a better approach

34

Easy push Easy push Easy push Hard push Hard push Hard push Hard push

Let’s look at it a different way: what happens if I spread the work over time?

Easy push

slide-35
SLIDE 35

Vector Growth: a better approach

35

Easy push Easy push Easy push Hard push Hard push Hard push Hard push

Let’s look at it a different way: what happens if I spread the work over time?

Easy push

slide-36
SLIDE 36

Vector Growth: a better approach

36

Easy push Easy push Easy push Hard push Hard push Hard push Hard push Easy push

Now compare with the “naive” approach

slide-37
SLIDE 37

Vector Growth: a better approach

37

Easy push Easy push Easy push Hard push Hard push Hard push Hard push Easy push

Now compare with the “naive” approach By simply adding one extra “slot” we roughly cut down the work by half (over several pushes)

slide-38
SLIDE 38

Can we do better?

38

slide-39
SLIDE 39

Vector Growth: a much better approach

std::vector<T> some_vector; So what is a vector really?

39

buffer_ = len_ = 5 capacity_ = 10

Vector (simplified)

O Z B Y L

1 2 3 4

I’ll Grow!!! I’ll double my size! O Z B Y L

1 2 3 4 5 6 7 8 9

slide-40
SLIDE 40

40

Vector Growth: a much better approach

slide-41
SLIDE 41

Vector Growth: a much better approach

41

Let’s spread the work over time

slide-42
SLIDE 42

Vector Growth: a much better approach

42

Let’s spread the work over time

slide-43
SLIDE 43

Vector Growth: a much better approach

43

Let’s spread the work over time

slide-44
SLIDE 44

Vector Growth: a much better approach

44

Let’s spread the work over time

slide-45
SLIDE 45

Vector Growth: a much better approach

45

Let’s spread the work over time

slide-46
SLIDE 46

Vector Growth: a much better approach

46

Let’s spread the work over time Over time I can spread my work so that I have 
 (OVER SEVERAL PUSHES) constant work

slide-47
SLIDE 47

Vector Growth: a much better approach

47

Let’s spread the work over time Amortized Analysis Over time I can spread my work so that I have 
 (OVER SEVERAL PUSHES) constant work

slide-48
SLIDE 48

Vector Growth summarized

If it grows by 1, O(n2) over time (n pushes - AMORTIZED ANALYSIS) If it grows by 2, push takes roughly half the“steps” but still O(n2) over time ( n pushes - AMORTIZED ANALYSIS) If it doubles its size, push takes O(1) over time (n pushes - AMORTIZED ANALYSIS)

48

slide-49
SLIDE 49

A steadily shrinking Stack

Let’s consider this application:

  • Push the 524,288th (219)element onto Stack which

causes it to double it’s size to 1,048,576 (220)


  • Reading an input file 

  • pop the elements that match

  • manipulate input record accordingly

  • repeat

49

slide-50
SLIDE 50

A steadily shrinking Stack

Let’s consider this application:

  • Push the 524,288th (219)element onto Stack which

causes it to double it’s size to 1,048,576 (220)


  • Reading an input file 

  • pop the elements that match

  • manipulate input record accordingly

  • repeat

50

How much I pop will depend on input

slide-51
SLIDE 51

A steadily shrinking Stack

Let’s consider this application:

  • Push the 524,288th (219)element onto Stack which

causes it to double it’s size to 1,048,576 (220)


  • Reading an input file 

  • pop the elements that match

  • manipulate input record accordingly

  • repeat

51

Assume a few matches at each iteration -> mostly empty stack but it will be around for a long time! U s e l e s s m e m

  • r

y w a s t e I will not shrink!

slide-52
SLIDE 52

Linked Chain

52

top_

slide-53
SLIDE 53

Linked Chain

53

top_ new_node_ptr

push

slide-54
SLIDE 54

Linked Chain

54

top_ new_node_ptr

push

slide-55
SLIDE 55

Linked Chain

55

top_ new_node_ptr

push

slide-56
SLIDE 56

Linked Chain

56

top_

slide-57
SLIDE 57

Linked Chain

57

top_

push

new_node_ptr

slide-58
SLIDE 58

Linked Chain

58

top_

push

new_node_ptr

slide-59
SLIDE 59

Linked Chain

59

top_

push

new_node_ptr

slide-60
SLIDE 60

Linked Chain

60

top_

push

new_node_ptr

slide-61
SLIDE 61

Linked Chain

61

top_

slide-62
SLIDE 62

Linked Chain

62

top_

slide-63
SLIDE 63

Linked Chain

63

pop

temp_ptr top_

slide-64
SLIDE 64

Linked Chain

64

pop

temp_ptr top_

slide-65
SLIDE 65

Linked Chain

65

pop

temp_ptr top_

slide-66
SLIDE 66

Linked Chain

66

pop

temp_ptr top_

slide-67
SLIDE 67

Linked Chain

67

top_

slide-68
SLIDE 68

Linked-Chain Analysis

1 assignment + 1 increment/decrement = O(1) size : O(1)
 isEmpty: O(1)
 push: O(1)
 pop : O(1)
 top : O(1) GREAT!!!! And there is no “Except” case here, every

  • peration is O(1)!

68

slide-69
SLIDE 69

To summarize

Array: O(1) for push and pop, but size is bounded Vector: size is unbounded but


  • Some push operations take O(1), others take

O(n) -> O(1) over time (AMORTIZED ANALYSIS)
 
 Linked-Chain: O(1) for push and pop and size is unbounded

69

slide-70
SLIDE 70

Implement Stack ADT

70

What should we add here to implement it as a linked chain? #ifndef STACK_H_
 #define STACK_H_
 
 template<<typename ItemType>
 class Stack 
 {
 
 public:
 Stack();
 void push(const ItemType& new_entry); //adds an element to top of stack
 void pop(); // removes element from top of stack
 ItemType top() const; // returns a copy of element at top of stack
 int size() const; // returns the number of elements in the stack
 bool isEmpty() const;//returns true if no elements on stack, else false 
 
 private:
 //implementation details here }; //end Stack
 
 #include "Stack.cpp"
 #endif // STACK_H_`

slide-71
SLIDE 71

Implement Stack ADT

#ifndef STACK_H_
 #define STACK_H_
 
 template<class T>
 class Stack 
 {
 
 public:
 Stack();
 ~Stack(); // destructor
 Stack(const Stack<T>& a_stack); //copy constructor
 void push(const T& newEntry); // adds an element to top of stack
 void pop(); // removes element from top of stack
 T top() const; // returns a copy of element at top of stack
 int size() const; // returns the number of elements in the stack
 bool isEmpty() const; //returns true if no elements on stack else false 
 private:
 Node<T>* top_; // Pointer to top of stack
 int item_count; // number of items currently on the stack }; //end Stack
 
 #include "Stack.cpp"
 #endif // STACK_H_

71