Chapter 6 – Queues and Deques 6.1 The Queue Abstract Data Type 6.2 Maintaining a Queue of Customers Chapter 6 – Queues and Deques
Lab 05 – Expressions
Requirements Input is an expression string in infix notation. Queues / Deques Input is an expression string in infix notation. Expression: 43 + 2 * 19 Use an ExpressionManager class to hold your infix, postfix, (and prefix) expressions. Your class should be derived from the abstract interface class ExpressionManagerInterface. Implement member functions: virtual int value(void); virtual string infix(void); virtual string postfix(void); virtual string prefix(void); Output the resulting infix, postfix, (prefix), and integer evaluation value of the expression. Your calculations should perform integer division and produce integer results.
Example Input / Output Input Input Output Output Queues / Deques Input Input Expression: 43 + 2 * 19 Infix: Postfix: Prefix: Value: Expression: 2 + 3 - 5 Infix: Postfix: Prefix: Value: Output Output Expression: 43 + 2 * 19 Infix: 43 + 2 * 19 Postfix: 43 2 19 * + Prefix: + 43 * 2 19 Value: 81 Expression: 2 + 3 - 5 Infix: 2 + 3 - 5 Postfix: 2 3 + 5 - Prefix: - + 2 3 5 Value: 0 Why not Prefix: + 2 - 3 5
ExpressionManagerInterface Queues / Deques //YOU MAY NOT MODIFY THIS HEADER INTERFACE #ifndef EXPRESSION_MANAGER_INTERFACE_H #define EXPRESSION_MANAGER_INTERFACE_H #include <string> using std::string; class ExpressionManagerInterface { public: ExpressionManagerInterface(void) {}; virtual ~ExpressionManagerInterface(void) {}; /** Return the integer value of the infix expression */ virtual int value(void) = 0; /** Return the infix items from the expression Throw an error if the expression 1) is not balanced. 2) the number of operators IS NOT one less than the number of operands. 3) there are adjacent operators. */ virtual string infix(void) = 0; /** Return a postfix representation of the infix expression */ virtual string postfix(void) = 0; /** (BONUS) Return a prefix representation of the infix expression */ virtual string prefix(void) { return "NOT IMPLEMENTED"; } /** Return the infix vector'd expression items */ virtual string toString(void) const = 0; }; #endif // EXPRESSION_MANAGER_INTERFACE_H ExpressionManager Inherits from ExpressionManagerInterface ExpressionManagerInterface ExpressionManager
ExpressionManager Inherits from ExpressionManagerInterface Queues / Deques class ExpressionManager : public ExpressionManagerInterface { private: string expression_; std::vector<string> inFix_; std::vector<string> postFix_; std::vector<string> preFix_; string operators = "([{ -+ */% "; public: ExpressionManager(string exp) : expression_(exp) { } ~ExpressionManager() { } virtual int value(void); /** Return the integer value of the infix expression */ virtual string infix(void); /** Return the infix expression / rejects invalid */ virtual string postfix(void); /** Return a postfix representation */ virtual string prefix(void); /** (BONUS) Return a prefix representation */ virtual string toString(void) const; /** Return an infix representation */ }; #endif // EXPRESSION_MANAGER_H Inherits from ExpressionManagerInterface Index/4 is the operator precedence.
Chapter 6 Objectives Queues / Deques To learn how to represent a waiting line (queue) with a Queue ADT and functions for insertion (push), removal (pop), and for accessing the element at the front (front). To understand how to implement the Queue ADT using a single-linked list, a circular array, and a double-linked list. To understand how to simulate the operation of a physical system that has one or more waiting lines using queues and random number generators. To introduce the standard library Deque class. The queue, like the stack, is a widely used data structure, but differs from a stack in one important way a stack is LIFO list – Last-In, First-Out while a queue is FIFO list – First-In, First-Out
6.1, pgs. 358-362 6.1 The Queue Abstract Data Type A Queue of Customers A Print Queue The Unsuitability of a "Print Stack'' Specification of the Queue ADT 6.1, pgs. 358-362
Queue Abstract Data Type Queues / Deques The queue, like the stack, is a widely used data structure, but differs from a stack in one important way a stack is LIFO list – Last-In, First-Out while a queue is FIFO list – First-In, First-Out A queue can be visualized as a line of customers waiting for service The next person to be served is the one who has waited the longest. New elements are placed at the end of the line.
A Queue of Customers Tom Anne Zack Queues / Deques To the left is a queue of three customers waiting to buy concert tickets Ticket agent Tom has been waiting the longest Tom Anne Zack Zack is the most recent arrival Tom will be the first customer removed from the queue (and able to buy tickets) when a ticket agent becomes available
A Queue of Customers Anne Zack Ticket agent Queues / Deques Ticket agent Anne will then become the first one in the queue Anne Zack Any new customers will be inserted in the queue after Zack
Print Queue Operating systems use queues to Queues / Deques Operating systems use queues to keep track of tasks waiting for a scarce resource ensure that the tasks are carried out in the order they were generated. Print queue: printing typically is much slower than the process of selecting pages to print, so a queue is used.
Why Not a “Print Stack”? Stacks are Last-In, First-Out (LIFO). Queues / Deques Stacks are Last-In, First-Out (LIFO). The most recently selected document would be the next to print. Unless the print stack is empty, your print job may never be executed if the printer is connected to a computer network and others are issuing print jobs.
Specification for a Queue Interface Queues / Deques Because only the front element of a queue is visible, the operations performed by a queue are few in number. We need to be able to retrieve the front element, remove the front element, push a new element onto the queue, and test for an empty queue. The functions above are all defined in the header file for the STL container queue, <queue>.
Specification for a Queue Interface Queues / Deques For queue names in (a), the value of names.empty() is false. string first = names.front(); stores "Jonathan" in first without changing names names.pop(); removes "Jonathan" from names. The queue names now contains four elements and is shown in (b) names.push("Eliana"); adds "Eliana" to the end of the queue; the queue names now contains five elements and is shown in (c)
6.2 Maintaining a Queue of Customers 6.2, pgs. 362-365
Queue Examples Queues / Deques Imagine you have a web-site which serves files to thousands of users. You can only handle 100 requests at a time. A fair policy would be first-come-first-serve - serve 100 at a time in order of arrival. In a multitasking operating system, the CPU cannot run all jobs at once. Jobs must be batched up and then scheduled according to some "FIFO" policy. The producer–consumer problem describes two processes, the producer and the consumer, who share a common buffer as a queue. The producer's job is to generate data and put it into the buffer. The consumer consumes the data one piece at a time.
Queue Examples Other computing examples: Other real world examples: Queues / Deques Other computing examples: In a breadth-first ("shallowest"-first) search of a graph, you would use a queue to store nodes as you discover them. Parallel processing with super computers use queues to synchronized parallel execution threads. Other real world examples: We wait in queues at check-out counters in grocery stores. We wait in queues to enter movie theaters. We wait in queues to drive on a turnpike. We wait in queues to ride on a roller coaster. Game Applications: Algorithms that explore mazes of interconnected rooms use queues to keep track of which options have not yet been explored. Avatars pass messages to one another.
Maintaining a Queue of Customers Queues / Deques Problem Write a menu-driven program Maintain_Queue that maintains a list of customers The user should be able to: insert a new customer in line display the customer who is next in line remove the customer who is next in line display the length of the line Analysis Inputs Operation selection New customer entry Outputs The effect of each operation
Maintaining a Queue of Customers Queues / Deques Design Maintain_Queue uses a queue<string> for customers. Algorithm for main While the user is not finished Display the menu and get the selected operation. Perform the selected operation. Use customers.push(name) to enter new customer into queue. Use customers.front() to retrieve/display who is next in line Use customers.pop() to remove next in line Use customers.size() to output how many are in line Implementation Use switch to select operation. Use enum? const?
Implementation Queues / Deques #include <iostream> #include <queue> #include <string> using namespace std; const string choices[] = { "push", "front", "pop", "size", "quit" }; enum { PUSH, FRONT, POP, SIZE, QUIT }; const int num_choices = 5; int main() { queue<string> customers; string name; int choice_num = 0; do cout << endl << "Options:" << endl; for (int i = 0; i < num_choices; i++) cout << " " << i << ": "; cout << choices[i] << endl; cout << "Select option: "; cin >> choice_num; ---------------------- } while (choice_num != QUIT); return 0; } switch (choice_num) { case PUSH: cout << "Enter new customer name: "; cin >> name; customers.push(name); break; } case FRONT: cout << "Customer " << customers.front(); cout << " is next in line" << endl; break; case POP: cout << "Customer " << customers.front(); cout << " removed from the line" << endl; customers.pop(); break; case SIZE: cout << "Size of line is "; cout << customers.size() << endl; break; case QUIT cout << "Leaving customer queue" << endl; break; default: cout << "Invalid selection" << endl; break;
Maintaining a Queue of Customers Queues / Deques Testing Normal operation: Verify that all customers are stored and retrieved in FIFO order. Thoroughly test the queue by selecting different sequences of queue operations. Error conditions: Select "0xxx". Select "quit". Customer "John Doe". Flush cin buffer.