Chapter 4: Stacks and Queues. Objectives Looking ahead – in this chapter, we’ll consider Stacks...
-
Upload
clarissa-claudia-halling -
Category
Documents
-
view
230 -
download
5
Transcript of Chapter 4: Stacks and Queues. Objectives Looking ahead – in this chapter, we’ll consider Stacks...
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
2Data 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
3Data 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
4Data Structures and Algorithms in C++, Fourth Edition
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
5Data 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 6
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 7
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 8
Stacks (continued)
Fig. 4.5 Implementing a stack as a linked list.
Data Structures and Algorithms in C++, Fourth Edition 9
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 10
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 11
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 12
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 13
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 14
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 15
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 16
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 17
Queues (continued)
Fig. 4.10 Linked list implementation of a queue
Data Structures and Algorithms in C++, Fourth Edition 18
Queues (continued)
Fig. 4.10 (continued) Linked list implementation of a queue
Data Structures and Algorithms in C++, Fourth Edition 19
Queues (continued)
Fig. 4.11 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 20
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 21
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
22Data 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
23Data 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
24Data 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 usedstack<int> stack1; // deque by defaultstack<int,vector<int>> stack2;// vectorstack<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()
25Data Structures and Algorithms in C++, Fourth Edition
Stacks in the Standard Template Library(continued)
Fig. 4.14 A list of stack member functions
26Data 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. 4.15 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 27
Queues in the Standard Template Library(continued)
• Notice dequeuing is implemented by front()and pop(), and enqueuing is implemented by push()
Fig. 4.16 An example application of queue’s member functions
Data Structures and Algorithms in C++, Fourth Edition 28
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
29Data Structures and Algorithms in C++, Fourth Edition
Priority Queues in the Standard Template Library (continued)
Fig. 4.17 A list of priority_queue member functions
• Use of these methods is shown in figure 4.18
30Data Structures and Algorithms in C++, Fourth Edition
Priority Queues in the Standard Template Library (continued)
Fig. 4.18 A program that uses member functions of the container priority_queue
31Data 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 32
Deques in the Standard Template Library(continued)
• A few of these operations are shown in figure 4.20
Fig. 4.20 A program demonstrating the operation of deque member functions
Data Structures and Algorithms in C++, Fourth Edition 33
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 34