Download presentation
Presentation is loading. Please wait.
1
Chapter 6 – Queues and Deques
6.4 The Deque 6.5 Simulating Waiting Lines Using Queues Chapter 6 – Queues and Deques
2
Attendance Quiz #21 Queues / Deques
3
Tip #23: Class or Function?
Queues / Deques Its not about class or function - its about being able to write more efficient and reusable code in developing powerful apps what would be too complicated to write without classes. OOP is generally about tying together state and behavior. Classes group attributes (state) and behavior (methods) and stating that only the methods (encapsulation) can act on the state. In OOP, the methods are responsible for implementing the behavior of the class. The methods participate in the encapsulation of state (freeing clients from the implementation detail) and in the preservation of the class invariants (statements about the class state that hold true from its birth to its death). Classes support polymorphism – the essence of OOP. Using OO over functions or older styles in a larger program is for portability. Easier, quicker, and more securer to pull out the information from a class. For a beginner it may seem you don't need classes for the little things, maybe… But even fairly simple programs could be vastly improved with classes - serious projects almost can't happen without them.
4
Converting from Infix to Prefix
Queues / Deques Scan the infix expression from right-to-left. If an operand, then prepend to output. Else, If the precedence of the scanned operator is greater than or equal to the precedence of the operator in the stack (or the stack is empty), push it on operator stack. Else, pop the operator from the stack until the precedence of the scanned operator is greater than or equal to the precedence of the operator residing on the top of the stack. Then, push the scanned operator on the stack. If the scanned character is an ‘)‘, push it to the stack. If the scanned character is an ‘(’, pop and output from the stack until an ‘)‘ is encountered. Repeat steps 2-5 until infix expression is scanned. Pop and prepend from the stack until it is empty.
5
6.4, pgs. 376-380 6.4 The Deque Specification of the Deque
Implementing the Deque Using a Circular Array The Standard Library Implementation of the Deque Exercises for Section 6.4 6.4, pgs
6
Deque ADT Queues / Deques A deque (double-ended queue) is an abstract data type that generalizes a queue, for which elements can be added to or removed from either the front (head) or back (tail). A deque differs from the queue abstract data type or First-In-First-Out List (FIFO), where elements can only be added to one end. Restricted deques are of two types: An input-restricted deque (IRDeque) is one where deletion can be made from both ends, but insertion can be made at one end only. An output-restricted deque (ORDeque) is one where insertion can be made at both ends, but deletion can be made from one end only. The C++ standard library defines the class std::deque to be a sequence that, like the std::vector, that supports random-access iterators (not supported by either the stack or the queue) in addition to constant-time insertion and removal from either end.
7
Specification of the Deque
Queues / Deques Behavior Member Function Insert element at back void push_back(item) Insert element at front void push_front(item)
8
Specification of the Deque
Queues / Deques Behavior Member Function Insert element at back void push_back(item) Insert element at front void push_front(item) Remove last element void pop_back(); Remove first element void pop_front();
9
Specification of the Deque
Queues / Deques Behavior Member Function Insert element at back void push_back(item) Insert element at front void push_front(item) Remove last element void pop_back(); Remove first element void pop_front(); Examine last element item& back(); Examine first element item& front();
10
Specification of the Deque
Queues / Deques Behavior Member Function Insert element at back void push_back(item) Insert element at front void push_front(item) Remove last element void pop_back(); Remove first element void pop_front(); Examine last element item& back(); Examine first element item& front(); Insert element iterator insert(iterator, item); Remove all items void remove(item);
11
Specification of the Deque
Queues / Deques Behavior Member Function Insert element at back void push_back(item) Insert element at front void push_front(item) Remove last element void pop_back(); Remove first element void pop_front(); Examine last element item& back(); Examine first element item& front(); Insert element iterator insert(iterator, item); Remove all items void remove(item); At item& at(index); Index item& []
12
Specification of the Deque
Queues / Deques Behavior Member Function Insert element at back void push_back(item) Insert element at front void push_front(item) Remove last element void pop_back(); Remove first element void pop_front(); Examine last element item& back(); Examine first element item& front(); Insert element iterator insert(iterator, item); Remove all items void remove(item); At item& at(index); Index item& [] Iterator start iterator begin(); Iterator end iterator end();
13
Specification of the Deque
Queues / Deques Behavior Member Function Insert element at back void push_back(item) Insert element at front void push_front(item) Remove last element void pop_back(); Remove first element void pop_front(); Examine last element item& back(); Examine first element item& front(); Insert element iterator insert(iterator, item); Remove all items void remove(item); At item& at(index); Index item& [] Iterator start iterator begin(); Iterator end iterator end(); Size size_t size();
14
STL Implementation of the Deque
Queues / Deques There are at least two common ways to efficiently implement a deque: A doubly linked list. A modified dynamic array The dynamic array approach uses a variant of a dynamic array that can grow from both ends, sometimes called array deques. These array deques have all the properties of a dynamic array, constant-time random access, good locality of reference, inefficient insertion/removal in the middle, And with the addition of amortized constant-time insertion/removal at both ends, instead of just one end.
15
STL Implementation of the Deque
Queues / Deques A deque, like a queue, can be implemented with a circular array. There are at three common ways to efficiently implement a deque in a circular buffer: Store the deque contents in a common circular buffer, and only resizing when the buffer becomes full. This decreases the frequency of resizings. Allocating deque contents from the center of the underlying array, and resizing the underlying array when either end is reached. This approach may require more frequent resizings and waste more space, particularly when elements are only inserted at one end. Storing contents in multiple smaller arrays, allocating additional arrays at the beginning or end as needed. Indexing is implemented by keeping a dynamic array containing pointers to each of the smaller arrays.
16
Circular Array Deque Queues / Deques A circular array makes random access straight forward: Return the ith element is at position front_index + i. Assuming that i starts at 0 and this sum is not larger than capacity. If larger than capacity, wrap around using modulo arithmetic. /** Returns a reference to an item in the deque. */ Item_Type& operator[](size_t i) { return the_data[(i + front_index) % capacity]; } A specialization of a randomly accessible circular array (CArray) is part of the standard deque implementation.
17
Circular Array Deque Queues / Deques The standard library implementation circular array contains pointers to fixed-size, dynamically allocated arrays that contain the data. The first data item is located at offset. The last data item is located at index (offset + num_items – 1) % BLOCK_SIZE in the last data block.
18
STL Implementation of the Deque
Queues / Deques The original designers chose this rather elaborate implementation rather than simply using a circular array because of the cost of reallocation. Even though we amortize the cost of the reallocation so that each push_front or push_back is a constant-time operation, the reallocation can take a significant amount of time. By storing only pointers in the circular array, the cost of reallocation is significantly reduced, because copying a pointer is a simple operation. Storing pointers to single objects in the circular array could work, but dynamically allocating small objects has a significant space overhead. Thus, by allocating an array of objects, we minimize this space overhead and minimize the cost of the reallocation. For large collections of large objects, the deque can be used instead of the vector to minimize space overhead and the cost of reallocation.
19
The Data Fields for the Deque
Queues / Deques /** Returns a reference to an item referenced by an index. @param i the index @return A reference to deque[i] */ template<typename Item_Type> Item_Type& deque<Item_Type>::operator[](size_t i) { if (i >= num_items) throw std::out_of_range("Invalid index deque::operator[]"); size_t block_index = (offset + i) / BLOCK_SIZE; size_t data_index = (offset + i) % BLOCK_SIZE; return the_data[block_index][data_index]; }
20
The push_back Function
Queues / Deques /** Pushes an item onto the back of the deque. @param item The item to be inserted. */ template<typename Item_Type> void deque<Item_Type>::push_back(const Item_Type& item) { size_t capacity = the_data.size() * BLOCK_SIZE; // Determine if the capacity needs to be increased. if ((num_items + offset) == capacity) the_data.push_back(new Item_Type[BLOCK_SIZE]); } num_items++; (*this)[num_items - 1] = item;
21
The pop_front Function
Queues / Deques /** Removes the front item from the deque. */ template<typename Item_Type> void deque<Item_Type>::pop_front() { offset++; if (offset == BLOCK_SIZE) delete[] the_data.front(); the_data.pop_front(); offset = 0; } num_items--;
23
18 – Sequential Containers
24
6.5, pgs. 380-398 6.5 Simulating Waiting Lines Using Queues
Case Study: Simulate a Strategy for Serving Airline Passengers Exercises for Section 6.5 Chapter Review, Exercises, and Programming Projects 6.5, pgs
25
Waiting Lines Simulation
Queues / Deques Simulation is used to study the performance of a physical system by using a physical, mathematical, or computer model of the system. Simulation allows designers of a new system to estimate the expected performance before building it. Simulation can lead to changes in the design that will improve the expected performance of the new system. Simulation is useful when the real system would be too expensive to build or too dangerous to experiment with after its construction. System designers often use computer models to simulate physical systems. Example: an airline check-in counter. A branch of mathematics called queuing theory studies such problems.
26
Case Study Queues / Deques Blue Skies Airlines (BSA) would like to have two waiting lines: regular customers frequent flyers Assuming only one ticket agent, BSA would like to determine the average wait time for taking passengers from the waiting lines using various strategies: take turns serving passengers from both lines (one frequent flyer, one regular, one frequent flyer, etc.) serve the passenger waiting the longest serve any frequent flyers before serving regular passengers
27
Case Study: Analysis Queues / Deques To run the simulation, we must keep track of the current time by maintaining a clock set to an initial time of zero. The clock will increase by one time unit until the simulation is finished. During each time interval, one or more of the following events occur(s): a new frequent flyer arrives in line a new regular flyer arrives in line the ticket agent finishes serving a passenger and begins to serve a passenger from the frequent flyer line the ticket agent finishes serving a passenger and begins to serve a passenger from the regular passenger line the ticket agent is idle because there are no passengers to serve
28
Case Study: Design Queues / Deques We can simulate different serving strategies by introducing a simulation variable frequent_flyer_max which represents the number of consecutive frequent flyer passengers served between regular passengers. When frequent_flyer_max is: 1, every other passenger served will be a regular passenger 2, every third passenger served will be a regular passenger a very large number, any frequent flyers will be served before regular passengers
29
Case Study: Design Queues / Deques
30
Case Study: Design Queues / Deques
31
Case Study: Design Queues / Deques
32
Case Study: Design Queues / Deques
33
Case Study: Design Queues / Deques
34
Case Study: Implementation
Queues / Deques
35
Case Study: Implementation
Queues / Deques
36
Case Study: Implementation
Queues / Deques
37
Case Study: Implementation
Queues / Deques
38
Case Study: Testing Queues / Deques
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.