Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Linked Multiple Queues. 2 A real world example. Not in the book. Sometimes we have a fixed number of items that move around among a fixed set of queues.

Similar presentations


Presentation on theme: "1 Linked Multiple Queues. 2 A real world example. Not in the book. Sometimes we have a fixed number of items that move around among a fixed set of queues."— Presentation transcript:

1 1 Linked Multiple Queues

2 2 A real world example. Not in the book. Sometimes we have a fixed number of items that move around among a fixed set of queues. Example: Process queues in an operating system.

3 3 Linked Multiple Queues We can take advantage of the fact that the number of items is fixed (or bounded). Provide an array with one element for each item to be queued plus one element for each queue (for a queue head). Each array element has a next and prev index. Always a member of exactly one queue. One queue is usually designated as the "Free Queue" Holds elements that are not in a real queue. Elements available to be assigned for use.

4 4 Linked Multiple Queues If we are queueing integers, 0 – N, we don’t need a data member. The position of the element defines the integer represented by that element. Example: Process IDs If we want to use this structure for other kinds of objects we can provide an array of objects or pointers to objects and map the integer to an object.

5 5 Getting Started Create a new empty C++ console application project. Add main.cpp Start with Hello, World Add class Linked_Multiqueue

6 6 Initial Program Add class Linked_Multiqueue. http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/ 2011_02_21_Linked_Multiqueues/

7 7 Class Linked_Multiqueue

8 8 Linked_Multiqueue.h #pragma once #include class Linked_Multiqueue { private: struct Node { int next; int prev; };

9 9 Linked_Multiqueue.h public: Linked_Multiqueue(int nr_queues, int nr_elements); ~Linked_Multiqueue(void); // Determine if the specified queue is empty. bool empty(int queue_id) const; // Return the integer at the head of the specified queue. int front(int queue_id) const; /* Move the element at the head of the "from" queue to * the tail of the "to" queue. */ void requeue (int from_queue_id, int to_queue_id); // Display all elements in the specified queue. void display(int queue_id, std::ostream & out) const;

10 10 Linked_Multiqueue.h private: // This method is to be used only by the constructor. void add_to_free_queue(int node_index);

11 11 Linked_Multiqueue.h private: /* Elements 0 through (nr_queues-1) are list headers for queues. * Elements nr_queues through (nr_queues+nr_elements-1) are queue * elements for integers 0 through N-1, where N is nr_elements. * The element for integer i is at (nr_queues+i). * * queues[queue_id].next is the first element of the queue. * (Oldest item and next item to be removed.) * queues[queue_id].prev is the last element of the queue. * (Most recently added item.) */ int number_of_queues; int number_of_elements; Node* queues; // Dynamically allocate array of Node objects };

12 12 Linked_Multiqueue.cpp #include #include "Linked_Multiqueue.h" // Constructor Linked_Multiqueue::Linked_Multiqueue(int nr_queues, int nr_elements) : number_of_queues(nr_queues), number_of_elements(nr_elements) { // Allocate array of Nodes queues = new Node[nr_queues + nr_elements]; assert (queues != 0); // Initialize all queues as empty. for (int i = 0; i < nr_queues; ++i) { queues[i].next = i; queues[i].prev = i; }

13 13 Constructor continued // Put all elements into the Free Queue (Queue 0). int first_node_index = nr_queues; int last_node_index = nr_queues + nr_elements - 1; for (int node_index = first_node_index; node_index <= last_node_index; ++node_index) { // Add this element to the end of queue 0; add_to_free_queue(node_index); }

14 14 add_to_free_queue() // Add the node at position node_index to the end of // the Free Queue. // This function is for use only by the constructor. void Linked_Multiqueue::add_to_free_queue(int node_index) { queues[node_index].prev = queues[free_queue].prev; queues[node_index].next = free_queue; int free_queue_tail_index = queues[free_queue].prev; queues[free_queue_tail_index].next = node_index; queues[free_queue].prev = node_index; }

15 15 empty() // Determine if the specified queue is empty. bool Linked_Multiqueue::empty(int queue_id) const { assert (queue_id >= 0); assert (queue_id < number_of_queues); return queues[queue_id].next == queue_id; }

16 16 display() // Display all elements in the specified queue. void Linked_Multiqueue::display(int queue_id, ostream & out) const { assert (queue_id >= 0); assert (queue_id < number_of_queues); if (empty(queue_id)) { out << "Queue " << queue_id << " is empty." << endl; } else { int i = queues[queue_id].next; // First element in this queue while (i >= number_of_queues) { out << i - number_of_queues << " "; i = queues[i].next; } out << endl; } out << endl }

17 17 Initial Test #include #include "Linked_Multiqueue.h" using namespace std; int main() { cout << "This is a test program for the linked multiqueue\n"; int nr_queues = 3; int nr_elements = 5; cout << "\nAllocating data structure.\n"; Linked_Multiqueue* lm1 = new Linked_Multiqueue(nr_queues, nr_elements); assert (lm1 != 0); cout << "Allocation successful\n"; for (int queue = 0; queue < nr_queues; ++queue) { cout << "Queue " << queue << endl; lm1->display(queue, cout); }

18 18 Initial Test Running

19 19 Destructor Linked_Multiqueue::~Linked_Multiqueue(void) { delete [] queues; }

20 20 front // Return the integer at the front of the specified queue. int Linked_Multiqueue::front(int queue_id) const { assert (queue_id >= 0); assert (queue_id < number_of_queues); return queues[queue_id].next - number_of_queues; }

21 21 requeue() /* Move the element at the head of the "from" queue to * the tail of the "to" queue. */ void Linked_Multiqueue::requeue (int from_queue_id, int to_queue_id) { assert (from_queue_id >= 0); assert (from_queue_id < number_of_queues); assert (to_queue_id >= 0); assert (to_queue_id < number_of_queues); assert (!empty(from_queue_id)); // First element in the "From" queue. int target = queues[from_queue_id].next;

22 22 requeue() continued // Remove target from its current queue int new_first = queues[target].next; queues[from_queue_id].next = new_first; queues[new_first].prev = from_queue_id; // Last element in the "To" queue int destination = queues[to_queue_id].prev; // Insert target at end of "To" queue. queues[destination].next = target; queues[target].prev = destination; queues[target].next = to_queue_id; queues[to_queue_id].prev = target; }

23 23 Test Requeue // Move all elements from their current queue // to the next higher numbered queue. for (int i = 0; i < nr_queues - 1; ++i) { cout << "\n\nMoving all elements from queue " << i << " to queue " << i+1 << endl; while (!lm1->empty(i)) { cout << "Moving head of queue " << i << " to queue " << i+1 << endl; lm1->requeue(i, i+1); cout << "Queue " << i << ":" << endl; lm1->display(i, cout); cout << "Queue " << i+1 << ":" << endl; lm1->display(i+1, cout); } cout << endl; }

24 24 Testing Requeue

25 25 More Testing // Move all elements of last queue back to first queue. cout << "\n\nMoving all elements from queue " << nr_queues-1 << " to queue " << 0 << endl; int i = nr_queues - 1; while (!lm1->empty(i)) { cout << "Moving head of queue " << i << " to queue " << 0 << endl; lm1->requeue(i, 0); cout << "Queue " << i << ":" << endl; lm1->display(i, cout); cout << "Queue " << 0 << ":" << endl; lm1->display(0, cout); } cout << endl;

26 26 Test Running

27 27 Test Delete cout << "\nDeleting the queues\n"; delete lm1; cout << "Test complete\n";

28 28 Testing Delete

29 29 What about copies? This class has no copy constructor or assignment operator. Will cause a crash if a user initializes a new object from and existing one or does an assignment. These are probably not operations that a user should do. How can we prevent it?


Download ppt "1 Linked Multiple Queues. 2 A real world example. Not in the book. Sometimes we have a fixed number of items that move around among a fixed set of queues."

Similar presentations


Ads by Google