2. Stack ADT
• Recall that ADT is abstract data type, a set
of data and a set of operations that act
upon the data.
• In a stack, the set of data is the stack of
elements.
• Stack is known as a LIFO (last-in-first-out)
data structure because the last data to
enter the stack is the first to exit the stack.
2
3. Stack ADT Operations
• push: places an element onto the top of a
stack.
• pop: removes an element from the top of the
stack.
• peek: which retrieves (copies) a value from the
top of the stack without removing it.
• an operation to determine whether or not the
stack is empty.
• an operation to empty out a stack.
3
4. Push
• Push means place a new data element at
the top of the stack
11
5
3 17
stack 4
5. Push (cont.)
• Push means place a new data element at
the top of the stack
11
3
5
17
stack 5
6. Push (cont.)
• Push means place a new data element at
the top of the stack
3
11
5
17
stack 6
7. Pop
• Pop means take a data element off the top
of the stack
3
11
5
17
stack 7
8. Pop (cont.)
• Pop means take a data element off the top
of the stack
3
11
5
17
stack 8
9. Pop (cont.)
• Pop means take a data element off the top
of the stack
11
5
3 17
stack 9
10. Peek
• Peek means retrieve the top of the stack
without removing it
3
11
5
3 17
stack 10
11. Array Stack Class Template
3 template <typename T>
4 class Stack {
5 public:
6 Stack() { … }
7 ~Stack( ) { … }
8 void push( T& elementToPush ) { … }
9 bool pop( T& poppedElement ) { … }
10 bool peek( T& topElement ) { … }
11 bool isEmpty( ) const { … }
12 void makeEmpty( ) { … }
13 private:
14 T* elements; // dynamic array used as an
15 int size; index to the top
16 int top; of the stack
17 };
11
14. Array Stack Pop
elements
125 25 200 70
0 1 2 3
top
An element can’t really be removed from an
array, as one would think pop would achieve.
14
15. Array Stack Pop
(cont.)
elements
client
125 25 200 70
0 1 2 3
top
The element 70 is at the top of the stack, and
what really happens during a pop, is that 70 is
returned to the client…
15
16. Array Stack Pop
(cont.)
elements
client
125 25 200 70
0 1 2 3
top
and top is decremented…
16
17. Array Stack Pop
(cont.)
elements
client
125 25 200 70
0 1 2 3
top
The element 70 is still in the array, but it is no
longer accessible. The next push will
overwrite it. Say, we would like to push 63…
17
18. Array Stack Push
elements
125 25 200 70
0 1 2 3
top
First, top is incremented…
18
19. Array Stack Push
(cont.)
elements
125 25 200 63
0 1 2 3
top
Then, 63 is pushed into that position…
19
20. Is the Array Stack Full/Empty?
• An array stack is full when
– top == size - 1
• An array stack is empty when
– top == -1
20
21. Linked-List Stack
• Stacks can also be implemented with a
linked list.
• The front node is the top of the stack.
21
22. Linked-List Stack
(cont.)
Bob
Ali
top
To pop, we remove the node at the front of the
linked list, and return the element to the client…
Ali
top
22
23. Linked-List Stack
(cont.)
Ali
top
To push Cat, we place the new element in a node
and insert it at the front of the linked list…
Cat
Ali
top
23
27. Linked-List Push into Empty Stack
32 void push( const T& element ) {
33 Node<T> *newNode = new Node<T>;
34 newNode->info = element;
35 if (top == NULL) { // if stack is empty.
36 newNode->next = NULL;
37 top = newNode;
38 } top NULL
39 else {
40 newNode->next = top;
41 top = newNode;
42 }
43 } newNode
27
28. Linked-List Push into Empty Stack
(cont.)
32 void push( const T& element ) {
33 Node<T> *newNode = new Node<T>;
34 newNode->info = element;
35 if (top == NULL) { // if stack is empty.
36 newNode->next = NULL;
37 top = newNode;
38 } top
39 else {
40 newNode->next = top;
41 top = newNode;
42 }
newNode
43 }
28
29. Linked-List Push into Non-Empty
Stack
32 void push( const T& element ) {
33 Node<T> *newNode = new Node<T>;
34 newNode->info = element;
35 if (top == NULL) { // if stack is empty.
36 newNode->next = NULL;
37 top = newNode;
38 } top
39 else { // stack is not empty.
40 newNode->next = top;
41 top = newNode;
42 }
43 } newNode
29
30. Linked-List Push into Non-Empty
Stack (cont.)
32 void push( const T& element ) {
33 Node<T> *newNode = new Node<T>;
34 newNode->info = element;
35 if (top == NULL) { // if stack is empty.
36 newNode->next = NULL;
37 top = newNode;
38 } top
39 else { // stack is not empty.
40 newNode->next = top;
41 top = newNode;
42 }
newNode
43 }
30
31. Linked-List Peek
56 bool peek( T& element )
57 {
58 if ( top == NULL )
59 return false;
60 element = top->info;
61 return true;
62 }
31
32. Linked-List Pop
56 bool pop( T& element )
57 {
58 if ( top == NULL )
59 return false;
60 element = top->info;
61 Node<T> *ptr = top;
62 top = top->next;
63 delete ptr;
64 return true;
65 }
32
33. Linked-List Stack
isEmpty and makeEmpty
65 bool isEmpty( ) const
66 {
67 return top == NULL;
68 }
69
70 void makeEmpty( )
71 {
72 T temp;
73 while ( pop( temp ) );
74 }
33
34. The Queue ADT
• The queue is a data structure that is like a
line of people
– When people join the line, they go at the end
– When people are served, they come off the
front of the line
• Queue is known as a FIFO (last-in, last-
out) data structure because the last data
to enter the queue is the last to exit from
the queue.
34
35. Queue ADT Operations
• enqueue: add an element to the end of
the line
• dequeue: take an element from the front
of the line
• peek: retrieve (copy) the element at the
front of the line without removing it
• an operation to determine whether or not
the queue is empty
• an operation that will empty out the queue
35
36. Queue (cont.)
• In addition to a pointer at the beginning of
the linked list (called front), a pointer to
the end of the linked list (called back) is
also maintained in the private section
• The back pointer makes it fast to add new
elements to the end of the queue – you
don’t have to use a loop to go all the way
through the queue to find the last node
36
43. Linked-List Queue Enqueue
21 void enqueue( const T & element )
22 {
23 Node<T> *newNode = new Node<T>;
24 newNode->info = element;
25 newNode->next = NULL;
28 if (front == NULL) { // list is empty.
29 front = back = newNode;
30 }
31 else { // list is not empty.
32 back->next = newNode;
33 back = newNode;
newNode
34 }
35 }
43
44. Linked-List Queue Enqueue (cont.)
22 void enqueue( const T & element )
23 {
24 Node<T> *newNode = new Node<T>;
25 newNode->info = element;
26 newNode->next = NULL;
back
27 if (front == NULL) { // list is empty.
28 front = newNode;
29 back = front;
front
30 }
31 else { // list is not empty. newNode
32 back->next = newNode;
33 back = newNode;
34 }
35 } Case 1: The queue
is initially empty.
44
45. Linked-List Queue Enqueue (cont.)
22 void enqueue( const T & element )
23 {
24 Node<T> *newNode = new Node<T>; front
25 newNode->info = element;
26 newNode->next = NULL;
27 if (front == NULL) { // list is empty.
28 front = newNode;
29 back = front;
30 }
back
31 else { // list is not empty.
32 back->next = newNode; newNode
33 back = newNode;
34 }
35 }
Case 2: The queue
has nodes.
45
46. Linked-List Queue Enqueue (cont.)
22 void enqueue( const T & element )
23 {
24 Node<T> *newNode = new Node<T>; front
25 newNode->info = element;
26 newNode->next = NULL;
27 if (front == NULL) { // list is empty.
28 front = newNode;
29 back = front;
30 }
31 else { // list is not empty. back
32 back->next = newNode; newNode
33 back = newNode;
34 }
35 }
Case 2: The queue
has nodes.
46
47. Linked-List Queue Dequeue
41 bool dequeue( T & deqElement )
42 {
43 if ( front == NULL) Returns false if client tries
44 return false; to dequeue an empty
queue.
Dequeue continued…
47
48. Linked-List Queue
Dequeue (cont.)
45 deqElement = front->info;
46 Node<T> *ptr = front;
47 front = front->next; deqElement:
48 delete ptr; passed in by
49 return true; reference
50 }
front ptr back
48
52. Linked-List Queue
isEmpty and makeEmpty
65 bool isEmpty( ) const
66 {
67 return front == NULL;
68 }
69
70 void makeEmpty( )
71 {
72 T temp;
73 while ( dequeue( temp ) );
74 }
52
53. Array Queue
• Similar to the linked-list queue, there are 2
attributes called front and back, but they
are indexes into an array instead of
pointers.
• When enqueuing, the back index is
incremented, and when dequeuing, the
front index is incremented.
53
54. Array Queue Class Template
3 template <typename T>
4 class Queue {
5 public:
6 Queue( ) { … }
7 ~Queue( ) { … }
8 void enqueue( T element ) { …
9 bool dequeue( T & deqElement ) { … }
10 bool peek( T & frontElement ) { … }
11 bool isEmpty( ) const { … }
12 void makeEmpty( ) { … }
13 private:
14 T *elements;
15 int size
16 int front;
17 int back;
54
18 };
65. Array Queue
Enqueue / Dequeue (cont.)
DEQUEUE
DEQUEUE
ENQUEUE
0 1 2 3 4 5 6 7
ENQUEUE
front back DEQUEUE
DEQUEUE
ENQUEUE
We have reached the DEQUEUE
end of array. How to
enqueue? ? DEQUEUE
ENQUEUE
65
66. Array Queue
Enqueue / Dequeue (cont.)
DEQUEUE
DEQUEUE
ENQUEUE
0 1 2 3 4 5 6 7
ENQUEUE
front back DEQUEUE
DEQUEUE
We could double the size of the array ENQUEUE
here. DEQUEUE
But if we keep doing this, we may DEQUEUE
have a million elements in the ENQUEUE
array, but only a few at the end are
66
used!
67. Array Queue
Enqueue / Dequeue (cont.)
DEQUEUE
DEQUEUE
ENQUEUE
0 1 2 3 4 5 6 7
ENQUEUE
back front DEQUEUE
DEQUEUE
We handle this problem by having the ENQUEUE
back wrap around to the beginning of DEQUEUE
the array. DEQUEUE
The front also wraps to the beginning ENQUEUE
when it reaches the end of the array 67
68. Is Array Queue Full/Empty?
• An array queue is empty when
– front = -1
• An array queue has one element when
– front = back
• An array queue is full when
– back + 1 = front
68
69. A Full Array Queue
0 1 2 3 4 5 6 7
back front
If the next operation is ENQUEUE, the array
capacity will need to be doubled
69
70. Reference
• Childs, J. S. (2008). Stack and Queue.
C++ Classes and Data Structures.
Prentice Hall.
70