Data Structures Chapter 4

Réussis tes devoirs et examens dès maintenant avec Quizwiz!

Array Unbounded Queue Class

Create a new larger array when needed and copy the queue into the new array. Since enlarging the array is conceptually a seperate operation from enqueueing, we implement it as a separate enlarge method. This method Instantiates an array with a size equal to the current capacity plus the original capacity We change the isFull method so that it always returns false, since an unbounded queue is never full. The dequeue and isEmpty methods are unchanged.

Link - Based Queue Implementations

For nodes we use the same LLNode class we used for the linked implementation of stacks. After discussing the link based approaches we compare all of our queue implementation approaches.

The Queue Interface

Like a stack, a queue is implemented with tools. We define overflow exceptions for both queue overflow and underflow. Our queues are generic Create a queueinterface containing abstract methods as a first step

Concurrency

Several interacting code sequences are executing simultaneously - through interleaving of statements of a single processor - through execution on several processors

Synchronized Queue

Similarly the synchronized keyword can be used to control access to an entire or selected parts of a data structure.

Array Based Implementation -

Two array based implementations of the Queue ADT, a bounded queue version and an unbounded queue version. Some figures are simplified by using a capital letter to represent an elements information.

Application: Average Waiting Time

We create a program that simulates a series of customers arriving for a service, entering a queue, waiting, being served, and finally leaving the queue. It tracks the time customeres spend waiting in queues and outputs the average waiting time.

Floating Front Design is much more effective and efficient than Fixed Front Design. It can also be used to wrap an added value around to the other side of the array if the last indexes are full

With Floating Front Design, when you perform the enqueue operation values are placed in the front of the array. When you perform the dequeue, it removes the first element from the array, and instead of moving the entire array, it moves the front to change index 1 from index 0

LinkedQueue Class

import support.LLNode; public class LinkedQueue<T> implements QueueInterface<T> { protected LLNode<T> front; // reference to the front of q protected LLNode<T> rear; // reference to the rear of q protected int numElements = 0; // num of elements in q public LinkedQueue() { front = null; rear = null; }

The Enlarge Operation

private void enlarge() { //create the larger array T[] larger = (T[]) new Object[elements.length + origCap]; //copy the contents from the smaller array into the larger int currSmaller = front; for (int currLarger = 0; currLarger < numElements; currLarger++) { larger[currLarger] = elements[currSmaller]; currSmaller = (currSmaller + 1) % elements.length; } // update instance variables elements = larger; front = 0; rear = numElements - 1; }

Code for Dequeue Operation Link Based Queue Implementations

public T dequeue() { if (isEmpty()) throw new QueueUnderflowException("Dequeue attempted on empty queue."); else { T element; element = front.getInfo(); front = front.getLink(); if (front == null) rear = null; numElements--; return element; } }

The Dequeue Operation

public T dequeue() { if (isEmpty()) throw new QueueUnderflowException("Dequeue attempted on empty queue."); else { T toReturn = elements[front]; elements[front] = null; front = (front + 1) % elements.length; numElements = numElements - 1; return toReturn; } }

The Queue Interface Code

public interface QueueInterface<T> { void enqueue(T element) throws QueueOverflowException; //Throws QueueOverflowException if queue is full; //Otherwise, adds element to the rear of this queue. T dequeue() throws QueueUnderflowException; //Throws QueueUnderflowException; //otherwise, removes front element from this queue and returns it. boolean isFull(); // returns true if this queue is full; //otherwise, returns false. boolean isEmpty(); //returns true if this queue is empty; //otherwise, returns false. int size(); // returns the number of elements in this queue. }

ArrayUnbounded Enqueue Operation

public void enqueue(T element) //adds element to rear of this queue { if (numElements == elements.length) enlarge(); rear = (rear + 1) % elements.length; elements[rear] = element; numElements = numElements + 1; }

Code For Enqueue Operation Link Based Queue Implementations

public void enqueue(T element) //adds element to the rear of this queue { LLNode<T> newNode = new LLNode<T>(element); if (rear == null) front = newNode; else rear.setLink(newNode); rear = newNode; numElements++; }

How to find the rear of the array

rear =(rear+1)% arr.len

Enqueue Operation

{ If (isFull()) Throw new QueueOverflowException("Enqueue attempted on a full queue"); Else { rear = (rear + 1) % elements.length; elements[rear] = element; numElements = numElements + 1; } }

Difference between .size and .length

.size measures total empty or full spaces in array .length measures only the spaces in the array that contain a value of some kind

Enqueue Operation Link Based Queue Implementations

1. Create a node for the new element 2. Add the new node at the rear of the queue 3. Update the reference to the rear of the queue 4. Increment the number of elements

The Enqueue Operation For Link Based Queue Implementations

1. Create a node for the new element 2. Add the new node at the rear of the queue 3. Update the reference to the rear of the queue 4. Increment the number of elements

The Dequeue Operation for Link Based Queue Implementations

1. Set element to the information in the front node 2. Remove the front node from the queue 3. If the queue is empty set the rear to null 4. Decrement the number of elements\ 5. Return element

Dequeue Operation Link Based Queue Implementations

1. Set element to the information in the front node 2. Remove the front node from the queue 3. if the queue is empty set the rear to null 4. Decrement the number of elements 5. Return element

Bounded Queue

A queue with a limited or bounded capacity for processes.

Queue

A structure in which elements are added to the rear and removed from the front. Has several constructors and transformers

Two operations for Enqueing

Add, that throws an exception if invoked on a full queue, and offer, that returns a boolean value of false if invoked on a full queue.

Queue Operator - Enqueue

Adds an element to the end of the queue(transformer)

Fixed Front Design

After four Calls to enqueue with arguments A, B, C, D: [A][B][C][D][ ] Dequeue the front element: [ ] [B] [C] [D] [ ] Move every element in the queue up one slot [B] [C] [D] [ ] [ ] This dequeue operation is inefficient, so we do not use this approach.

Four library classes that implement the Dequeue interface

ArrayDequeue, ConcurrentLinkedDequeue, LinkedBlockingDequeue, and linkedList

Test for palindrome (String Candidate)

Create a new stack Create a new queue For each character in candidate if the character is a letter change letter to lowercase push to the character onto the stack enqueue the character onto the queue Set stillPalindrome to true While(there are still more characters in the structures && stillPalindrome) Pop fromStack from the stack Dequeue fromQueue from the queue If(fromStack != fromQueue) Set stillPalindrome to false Return(stillPalindrome)

Queue Operator - New

Creates an empty queue (Constructor)

When to throw exceptions in queue

If queue is full and enqueue attempted, throw overflow exception. If queue is empty and dequeue is attempted, throw underflow exception.

Inheritance of Interfaces

Java supports inheritance of interfaces, in fact the language supports mulitple inheritance of interfaces - A single interface can extend any number of other interfaces. Suppose that interface A extends interface B. Then a class that implements interface B must provide concrete methods to extend all of the abstract methods listed in both interface B and interface A.

Queue Methods :

Moves in from rear and out from front. isEmpty(); isFull(); size(); enqueue(); dequeue();

Using Queues

Operating Systems often maintain a queue of processes that are ready to execute or that are waiting for a particular event to occur. Another important application of the queue data structure is to help us simulate and analyze such real worlds queues.

Exceptional Situations

Our queues throw exceptions in the case of underflow or overflow. Another approach to prevent the over/underflow from occuring by nullifying the operation, and returning a value that indicates failure. Boolean enqueue (T element) adds element to the rear of this queue, returns true if successfully added, returns false otherwise. T dequeue() returns null if the queue is empty, otherwise removes the front element from this queue and returns it.

Unbounded Queue

Queue that does not have a limited capacity

Front and Rear

References of the index's of the array that are the first and last

Queue Operator - Dequeue

Removes and returns the front element of the queue

Comparing Queue Implementations

Storage Size Array Based: Takes the same amount of memory, no matter how many array slots are actually used, proportional to current capacity. Link Based: Takes space proportional to actual size of the queue(but each element requires more space with array approach) Operation Efficiency All operations, for each approach, are O(1) Except for the constructors: Array Based - O(N) Link Based - O(1) Special Case - For the ArrayUnboundedQueue the size penalty can be minimized but the enlarge method is O(N)

Elements are always removed from which direction of a queue

The Front

The Test Method

The test method creates both a stack and a queue. It then repeatedly pushes each input letter onto the stack, and also enqueues the letter onto the queue. It discards any non letter characters. To simplify the comparision later, we push and enqueue only lowercase versions of the characters After the characters of the candidate string have been processed, test repeatedly pops a letter from the stack and dequeues a letter from the queue. As long as these letters match each other throughout the process, it is a palindrome.

The Palindrome Class

To help us identify strings, we create a class called palindrome, with a single export static method test. Test takes a candidate string argument and returns a boolean Value indicating whether the string is a palindrome. Since test is static we invoke it using the name of the class rather than instantiating an object of the class. The test method uses both the queue and stack data structures.


Ensembles d'études connexes

Chem AP Classroom Midterm Review

View Set