Stack / Queue ADT Stack ADT Implementations Array resizing Queue ADT January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 1
Announcements • PA1 GradeScope being configured, will be available soon January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 2
Stacks in computing • Program execution & function calling • Postfix evaluation – e.g. 5 1 2 + 4 * + 3 – – Place numbers in a stack, apply operator to last two numbers • My e-mail inbox? January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 3
The stack ADT • A stack only allows items to be inserted and removed at one end – We call this end the top of the stack – The other end is called the bottom • Access to other items in the stack is not allowed • A stack can be used to naturally store data for postfix notation – Operands are stored at the top of the stack – And removed from the top of the stack • Notice that we have not (yet) discussed how a stack should be implemented – Just what it does • An example of an Abstract Data Type January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 4
Stack behaviour • A stack ADT should support at least the first two of these operations: – push – insert an item at the top of the stack – pop – remove and return the top item Must also have – peek – return the top item constructor(s) and destructor – is_empty – does the stack contain any items • ADT operations should be performed efficiently – The definition of efficiency varies from ADT to ADT – The order of the items in a stack is based solely on the order in which they arrive January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 5
Stack implementation • The stack ADT can be implemented using a variety of data structures, e.g. – Linked lists – Arrays • Both implementations must implement all the stack operations – In constant time (time that is independent of the number of items in the stack) January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 6
Stack implementation Using a linked list • Recall linked list construction from previous lessons – New nodes added at the “null” end of the list – Or inserted anywhere in the list • Implement a linked-list stack by adding/removing from the front of the list a a 18 18 27 27 52 52 34 34 January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 7
Stack implementation Using arrays • We need to keep track of the index that represents the top of the stack – When we insert an item increment this index – When we delete an item decrement this index • Insertion or deletion time is independent of the number of items in the stack January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 8
Array stack example index of top is current size – 1 Stack st(); st.push(6); //top = 0 st.push(1); //top = 1 6 1 7 8 st.push(7); //top = 2 0 1 2 3 4 5 st.push(8); //top = 3 st.pop(); //top = 2 January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 9
Array stack implementation summary • Easy to implement a stack with a (dynamic) array – And push and pop can be performed in constant time • Once the array is full – No new values can be inserted or – A new, larger, array can be created • And the existing items copied to this new array • This will take linear time, but should occur only rarely January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 10
Running time considerations • Linked list implementation – push and pop simply call insert or remove from front of list – All operations 𝑃 1 • Array implementation – push to full array requires 𝑃 𝑜 resize – resize by a constant factor (e.g. capacity = 2 * capacity; ) leads to 𝑃 1 average cost per operation – resize by a constant amount (e.g. capacity = capacity + 500;) leads to 𝑃 𝑜 average cost per operation • Cache performance – array implementation has superior cache performance January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 11
Queues January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 12
Queues • In a queue items are inserted at the back (end/tail) and removed from the front (head) • Queues are FIFO (First In First Out) data structures – fair data structures • Applications include: – Server requests • Instant messaging servers queue up incoming messages • Database requests – Print queues – Operating systems often use queues to schedule CPU jobs – The waiting list for this course! (it’s presumably fair) – Various algorithm implementations January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 13
Queue operations • A queue should implement at least the first two of these operations: – enqueue – insert item at the back of the queue – dequeue – remove an item from the front – peek – return the item at the front of the queue without removing it – isEmpty – check if the queue does not contain any items • Like stacks, it is assumed that these operations will be implemented efficiently – That is, in constant time January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 14
Queue implementation Using an array • Consider using an array as the underlying structure for a queue, we could – Make the back of the queue the current size of the array, much like the stack implementation – Initially make the front of the queue index 0 – Inserting an item is easy • What to do when items are removed? – Either move all remaining items down – slow – Or increment the front index – wastes space January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 15
Circular arrays • Trick : use a circular array to insert and remove items from a queue in constant time • The idea of a circular array is that the end of the array “wraps around” to the start of the array 7 0 6 1 2 0 2 3 4 6 1 5 7 5 3 4 January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 16
The modulo operator • The mod operator (%) calculates remainders: – 1%5 = 1, 2%5 = 2, 5%5 = 0, 8%5 = 3 • The mod operator can be used to calculate the front and back positions in a circular array – Thereby avoiding comparisons to the array size – The back of the queue is: Member attributes: • (front + num) % arrlength int front; • where num is the number of items in the queue int arrlength; int* arr; – After removing an item, the front of the queue is: int num; • (front + 1) % arrlength January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 17
Array queue example 0 0 1 Queue q; front num q.enqueue(6); 6 0 1 2 3 4 5 Insert item at (front + num) % queue.length, then increment num January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 18
Array queue example 2 0 1 3 5 4 Queue q; front num q.enqueue(6); q.enqueue(4); q.enqueue(7); 6 4 7 3 8 q.enqueue(3); q.enqueue(8); 0 1 2 3 4 5 q.dequeue(); Insert item at (front + num) % queue.length, then increment num q.dequeue(); Remove item at front, then decrement num and make front = (front + 1) % queue.length January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 19
Array queue example 2 5 3 4 Queue q; front num q.enqueue(6); q.enqueue(4); q.enqueue(7); 5 7 3 8 9 q.enqueue(3); q.enqueue(8); 0 1 2 3 4 5 q.dequeue(); Insert item at (front + num) % queue.length, then increment num q.dequeue(); Remove item at front, then decrement num q.enqueue(9); and make front = (front + 1) % queue.length q.enqueue(5); Need to check that the back of the queue does not overtake the front January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 20
Array queue resizing • Suppose we have an array-based queue and we have performed some enqueue and dequeue operations – Then we perform more enqueues to fill the array – How should we resize the array to allow for more enqueue operations? 12 5 76 33 2 41 front ? ? ? ? ? ? ? ? ? ? ? ? January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 21
Queue implementation Using a Linked List • Removing items from the front of the queue is straightforward • Items should be inserted at the back of the queue in constant time – So we must avoid traversing through the list – Use a second node pointer to keep track of the node at the back of the queue • Requires a little extra administration Member attributes: Node* front; Node* back; int num; January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 22
List queue example Queue q; q.enqueue(6); front 6 q.enqueue(4); q.enqueue(7); 4 back q.enqueue(3); q.dequeue(); 7 3 January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 23
Deques Double-ended queues • A deque combines stack and queue functionality – insertions and removals can happen at both ends . . . • What kind of structure, with what features, can produce 𝑃 1 performance for all insertions and removals? January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 24
Readings for this lesson • Carrano & Henry – Chapter 6 (Stack) – Chapter C1.3 (Templates) – Carrano & Henry: Chapter 13.1 – 13.2 (Queue) • Next class: – Carrano & Henry: Chapter 2 (Recursion) – Carrano & Henry: Chapter 11.2.1 (Merge sort) January 27, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 25
Recommend
More recommend