# Chapter 4: Stacks and Queues

## Presentation on theme: "Chapter 4: Stacks and Queues"— Presentation transcript:

Chapter 4: Stacks and Queues

Objectives Looking ahead – in this chapter, we’ll consider Stacks
Queues Priority Queues Stacks in the Standard Template Library Queues in the Standard Template Library Priority Queues in the Standard Template Library Deques in the Standard Template Library Data Structures and Algorithms in C++, Fourth Edition

Introduction ADTs allow us to defer the implementation details of data structures and focus on operations The operations themselves often determine which structure is most appropriate in a given situation In this chapter we’ll consider two such structures, stacks and queues, where we’ll focus on operations first Once we have determined what operations are needed and how they behave, we’ll consider implementations Data Structures and Algorithms in C++, Fourth Edition

Stacks A stack is a restricted access linear data structure
It can only be accessed at one of its ends for adding and removing data elements A classic analogy is of a stack of trays in a cafeteria; trays are removed from the top and placed back on the top So the very first tray in the pile is the last one to be removed For this reason, stacks are also known as last-in first-out (LIFO) structures We can only remove items that are available, and can’t add more items if there is no room, so we can define the stack in terms of operations that change it or report its status Data Structures and Algorithms in C++, Fourth Edition

Fig. 4.1 A series of operations executed on a stack
Stacks (continued) These operations are: clear( ): clears the stack isEmpty( ): determines if the stack is empty push(el): pushes the data item el onto the top of the stack pop( ): removes the top element from the stack topEl( ): returns the value of the top element of the stack without removing it A series of pushes and pops is shown in figure 4.1 Fig. 4.1 A series of operations executed on a stack Data Structures and Algorithms in C++, Fourth Edition

Stacks (continued) Stacks are particularly useful in situations where data have to be stored and processed in reverse order There are numerous applications of this Evaluating expressions and parsing syntax Balancing delimiters in program code Converting numbers between bases Processing financial data Backtracking algorithms An example of delimiter processing is shown in figure 4.2 (page 134), a second example deals with adding large numbers (figure 4.3, page 135) Data Structures and Algorithms in C++, Fourth Edition

Fig. 4.4 A vector implementation of a stack
Stacks (continued) Let’s now turn our attention to implementing the stack ADT One possible implementation uses a vector (figure 4.4) Fig. 4.4 A vector implementation of a stack Data Structures and Algorithms in C++, Fourth Edition

Fig. 4.4 (continued) A vector implementation of a stack
Stacks (continued) Fig. 4.4 (continued) A vector implementation of a stack A second implementation of the stack is as a doubly linked list, shown in figure 4.5 Data Structures and Algorithms in C++, Fourth Edition

Fig. 4.5 Implementing a stack as a linked list.
Stacks (continued) Fig. 4.5 Implementing a stack as a linked list. Data Structures and Algorithms in C++, Fourth Edition

Fig. 4.5 (continued) Implementing a stack as a linked list.
Stacks (continued) Fig. 4.5 (continued) Implementing a stack as a linked list. Figure 4.6 shows the push and pop operations of figure 4.1 using the vector (figure 4.6b) and linked list (figure 4.6c) implementations Data Structures and Algorithms in C++, Fourth Edition

Stacks (continued) Fig. 4.6 A series of operations executed on (a) an abstract stack and the stack implemented (b) with a vector and (c) with a linked list Data Structures and Algorithms in C++, Fourth Edition

Queues A queue, like a stack, is a restricted access linear data structure Unlike a stack, both ends are involved, with additions restricted to one end (the rear) and deletions to the other (the front) Since an item added to the queue must migrate from the rear to the front before it is removed, items are removed in the order they are added For this reason, queues are also known as first-in first-out (FIFO) structures Data Structures and Algorithms in C++, Fourth Edition

Queues (continued) The functions of a queue are similar to those of a stack Typically, the following methods are implemented clear( ): clears the queue isEmpty( ): determines if the queue is empty enqueue(el): adds the data item el to the end of the queue dequeue( ): removes the element from the front of the queue firstEl( ): returns the value of the first element of the queue without removing it A series of enqueues and dequeues is shown in figure 4.7 Note that this time both ends of the structure must be managed Data Structures and Algorithms in C++, Fourth Edition

Fig. 4.7 A series of operations executed on a queue
Queues (continued) Fig. 4.7 A series of operations executed on a queue One way a queue may be implemented utilizes an array, although care must be exercised In particular, as items are removed from the queue, spaces open up in the front of the array, which should not be wasted So items may be added to the “end” of the queue at the beginning of the array This treats the array as though it were circular, shown in figure 4.8c Data Structures and Algorithms in C++, Fourth Edition

Queues (continued) Fig. 4.8 (a–b) Two possible configurations in an array implementation of a queue when the queue is full; (c) the same queue viewed as a circular array As the circular array illustrates, the queue is full if the first and last elements are adjacent However, based on the actual array, this can occur in two situations, shown in figure 4.8(a) and figure 4.8(b): The first element is in the first location, and the last element in the last The first element is immediately after the last element Data Structures and Algorithms in C++, Fourth Edition

Queues (continued) This also means that the enqueue( ) and dequeue( ) operations have to deal with wrapping around the array Adding an element may require placing it at the beginning of the array (figure 4.8d) or after the last element (figure 4.8e) if there is room, even though the circular array doesn’t distinguish these (figure 4.8f) Fig. 4.8 (continued) (f) Enqueuing number 6 to a queue storing 2, 4, and 8; (d–e) the same queue seen as a one- dimensional array with the last element (d) at the end of the array and (e) in the middle Data Structures and Algorithms in C++, Fourth Edition

Queues (continued) Figure 4.9 (pages 142 and 143) shows some possible implementations of methods to work on such a queue A second, more flexible implementation of a queue is as a doubly linked list, either coded directly or as an STL list This is shown in figure 4.10 Figure 4.11 shows the same enqueue and dequeue operations that were illustrated in figure 4.7 They also indicate the changes that are needed in the queue when implemented as an array (figure 4.11b) or linked list (figure 4.11c) Data Structures and Algorithms in C++, Fourth Edition

Fig. 4.10 Linked list implementation of a queue
Queues (continued) Fig Linked list implementation of a queue Data Structures and Algorithms in C++, Fourth Edition

Fig. 4.10 (continued) Linked list implementation of a queue
Queues (continued) Fig (continued) Linked list implementation of a queue Data Structures and Algorithms in C++, Fourth Edition

Queues (continued) Fig A series of operations executed on (a) an abstract queue and the queue implemented (b) with an array and (c) with a linked list Data Structures and Algorithms in C++, Fourth Edition

Queues (continued) Queues are used in a wide variety of applications, especially in studies of service simulations This has been analyzed to such an extent that a very advanced body of mathematical theory, called queuing theory, has been developed to deal with it Data Structures and Algorithms in C++, Fourth Edition

Priority Queues In some circumstances, the normal FIFO operation of a queue may need to be overridden This may occur due to priorities that are associated the elements of the queue that affect the order of processing In cases such as these, a priority queue is used, where the elements are removed based on priority and position The difficulty in implementing such a structure is trying to accommodate the priorities while still maintaining efficient enqueuing and dequeuing Elements typically arrive randomly, so their order typically reflects no specific priority Data Structures and Algorithms in C++, Fourth Edition

Priority Queues (continued)
The situation is further complicated because there are numerous priority scenarios that could be applied There are several ways to represent priority queues With linked lists, one arrangement maintains the items in entry order, and another inserts them based on priority Another variation, attributed to Blackstone (Blackstone et. al. 1981) uses a short ordered list and larger unordered list Items are placed in the shorter list based on a calculated threshold priority On some occasions, the shorter list could be emptied, requiring the threshold to be dynamically recalculated Data Structures and Algorithms in C++, Fourth Edition

Priority Queues (continued)
As an alternative, the short list could always have the same number of elements; 𝑛 is a suggested size Yet another suggestion, by Hendriksen (1977, 1983) uses a linked list and an array of pointers to define a range within which the new element is added Empirical studies have indicated that linked lists by themselves aren’t useful for more than ten elements The two list variation varies considerably in usefulness depending on the calculated priorities Hendriksen’s implementation, however, works well regardless of priorities or amount of data Data Structures and Algorithms in C++, Fourth Edition

Stacks in the Standard Template Library
The STL implements the stack as a container adaptor This is not a new container, merely an adaptation of an existing one to make the stack behave in a specific way The deque is the default container, but lists and vectors can also be used stack<int> stack1; // deque by default stack<int,vector<int>> stack2;// vector stack<int,list<int>> stack3; // list The stack container methods are shown in figure 4.14 Notice that pop()does not return a value; to implement this, pop()must be combined with top() Data Structures and Algorithms in C++, Fourth Edition

Stacks in the Standard Template Library (continued)
Fig A list of stack member functions Data Structures and Algorithms in C++, Fourth Edition

Queues in the Standard Template Library
By default, the queue in the STL is implemented as an adapted deque, although a list can be used instead Figure 4.15 shows the methods for a queue Fig A list of queue member functions These methods are illustrated in the program in figure 4.16 Data Structures and Algorithms in C++, Fourth Edition

Queues in the Standard Template Library (continued)
Notice dequeuing is implemented by front()and pop(), and enqueuing is implemented by push() Fig An example application of queue’s member functions Data Structures and Algorithms in C++, Fourth Edition

Priority Queues in the Standard Template Library
The STL implements priority queues using the vector container, although the deque container may also be used Order is applied to the queue by keeping the item with highest priority in front This is handled by the push()method, which uses a Boolean function to reorder the queue’s elements The function may be user supplied, but if not, it defaults to < so that the highest-valued element has the highest priority This can also be set to > if the lowest-valued item should have the highest priority A list of methods for a priority queue is given in figure 4.17 Data Structures and Algorithms in C++, Fourth Edition

Priority Queues in the Standard Template Library (continued)
Fig A list of priority_queue member functions Use of these methods is shown in figure 4.18 Data Structures and Algorithms in C++, Fourth Edition

Priority Queues in the Standard Template Library (continued)
Fig A program that uses member functions of the container priority_queue Data Structures and Algorithms in C++, Fourth Edition

Deques in the Standard Template Library
A deque (double-ended queue) is a variation of the queue where additions and deletions can be made at both ends This can be easily represented using a doubly linked list, which is incorporated into the STL list container The STL adds additional functionality to the deque in the ability to access any element randomly, like arrays and vectors This implies the STL deque effectively combines the behaviors of vectors and lists A list of the member functions for deques is given in figure 4.19 on pages 154 and 155 Data Structures and Algorithms in C++, Fourth Edition

Deques in the Standard Template Library (continued)
A few of these operations are shown in figure 4.20 Fig A program demonstrating the operation of deque member functions Data Structures and Algorithms in C++, Fourth Edition

Deques in the Standard Template Library (continued)
The STL deque has an interesting implementation While random access can be simulated by redefining the operator[] to include a loop that scans to a particular node, the actual implementation is quite different Rather than using a linked list, the STL deque is implemented as an array of pointers to blocks or arrays of data Depending on storage needs, the number blocks can change, and the number of pointers will change based on this Data Structures and Algorithms in C++, Fourth Edition

Similar presentations