0% found this document useful (0 votes)
2 views44 pages

Lecture 14 - Queue Implementation

This document covers the implementation of the Queue Abstract Data Type (ADT) in Java, detailing its operations, types, and methods for both array-based and linked list-based implementations. It includes lecture objectives, examples of queue operations, and exercises for students to practice coding and testing their implementations. The document also discusses Java's built-in Queue interface and provides a framework for creating user-defined queue classes with essential methods like enqueue, dequeue, peek, and size.

Uploaded by

plutoagcorp
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views44 pages

Lecture 14 - Queue Implementation

This document covers the implementation of the Queue Abstract Data Type (ADT) in Java, detailing its operations, types, and methods for both array-based and linked list-based implementations. It includes lecture objectives, examples of queue operations, and exercises for students to practice coding and testing their implementations. The document also discusses Java's built-in Queue interface and provides a framework for creating user-defined queue classes with essential methods like enqueue, dequeue, peek, and size.

Uploaded by

plutoagcorp
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 44

CSI247:

Data Structures

Lecture 14 – Queue ADT


implementation
Department of Computer Science
B. Gopolang (247-275)
Previous lesson
● Stack
• ADT based on LIFO approach
• Stack operations:
• All take place on one end of the Stack (top)
• Add to Stack: push()
• Delete from Stack: pop()
• Checking Stack’s top element: peek()
• Many stack application areas, e.g.:
• Undo mechanism (text editors)
• Back button (web browsers)
• Addresses of recently visited sites 2
● Stack implementation
a) Using an array: elements stored contiguously in an array
• Good: Direct access to elements (via array index)
• Bad: Size restriction
b) Using a linked list: elements stored as Nodes, connected
through pointers
• Good: No size limitation
• Bad: No direct access to middle Nodes

3
Today …

Implementing our own


Queue class

4
Lecture Objectives

● By the end of this lecture you must be able to:


• Implement Queue class using:
• An array
• Linked List

5
1. Queue Review
● A linear data structure, uses FIFO principle!
• Uses FIFO: First In First Out!
• Has front/head & tail/rear
● Inserting an element Dequeue
(remove)
front tail
• AKA enqueue
c y b m
• Elements join at the tail
Enqueue
● Removing an element (add)

• AKA dequeue
• Elements exit from front
● Many queue application areas, e.g.
• printer queue, keystroke queue, CPU processes, etc. 6
Illustration of Queue methods
Assuming an empty queue:

front tail
a) enqueue (19) 19

b) enqueue (28) 19 28

c) enqueue (35) 19 28 35

d) dequeue() 19 28 35

7
Exercise 1

a) Perform the following operations on an empty Queue:


enqueue(52), enqueue(96), enqueuer(63), dequeue(),
enqueue(28), enqueuer(86), dequeue(), enqueue(69), dequeue()
b) What is the sequence of dequeued values?
c) What would be the queue length after performing the
above sequence of operations?
d) Which item will be in front? At the tail?

8
Types of queues
a) Normal queue (FIFO) – standard queue

b) Circular Queue (Normal Queue)


• Last element is connected to the first element,
forming a circle

c) Double-ended Queue (Deque)


• A double-ended queue
• Insertions and deletions allowed at both front & tail
9
d) Priority Queue
• More specialized type
• Similar to Queue
• Has front and tail
• Removals from the front
• BUT
• Items are ordered by key value
• Item with the lowest/highest key is always in
front
• Insertions done to maintain ordering
• Used in multitasking operating system.
• Normally represented using heap data structure, but can
also use array & linked list
10
2. Java’s Queue Implementation
● Rem:
• An interface, in java.util
• Declaration:
public interface Queue<E> extends Collection<E>
• MUST be implemented by a concrete class
● Examples:
• PriorityQueue:
• Queue<Integer> pq = new PriorityQueue<Integer> ();
• LinkedList:
• Queue<String> list = new LinkedList<String>();
• ArrayDeque:
• Queue<Student> ad = new ArrayDeque<>(); 11
Queue methods in Java Implementation
● Rem:
• Queue inherit from Collection
• Hence, it includes some of methods from Collection
• And adds its own method(s) (peek())
● Commonly used Queue methods:
• add() – Insert element into a queue.
• remove() – Removes and returns element at the front
• Throws an exception when queue is empty
• peek() - Returns element at the front of the queue
• Not defined in Collection interface! 12
User-Defined Queue Implementation
• 2 options
a) Using an array
• Working with fixed-size structure (disadvantage)
• Remove from front, insert at the back (tail)
• Careful: Overflow!!! (ArrayIndexOutOfBounds)

b) Using a Linked List


• We use a Singly LinkedList
• No size restriction
• Queue will grow & shrink dynamically
13
● Common Queue operations to implement
• enqueue(): inserts element (at the tail)
• dequeue(): removes & return element (from front)
• peek(): returns element in front of queue
• Item is NOT removed!!!
• size(): returns # of elements in the queue
• isEmpty(): Checks if queue is empty
• Cannot dequeue when empty!
• isFull(): Checks if queue is full
• Cannot enqueue when full!
• printQueue(): prints all queue elements
14
a) Implementing Queue using an array
Note:
• There is need to keep track of 2 positions
• front: for beginning of Queue
• tail: for end of Queue
• Initially, they point to the same index
• Must be < 0 (smaller than smallest array index)
• We will use -1
front tail

0 1 2 3 4 5 15
How does enqueue() affect front and tail?

front tail

enqueue(26): 1st element: 26


0 1 2 3 4 5
front tail

enqueue(69): 2nd element: 26 69


0 1 2 3 4 5

front tail

enqueue(48): 3rd element: 26 69 48


0 1 2 3 4 5
16
How does dequeue() affect front & tail?
front front tail

1st dequeue(): 26 69 48
0 1 2 3 4 5
front front tail

2nd dequeue(): 26 69 48
0 1 2 3 4 5
◦ Note:
◦ dequeue() removes item from the queue, NOT the array
◦ Happens in front
◦ front will keep on increasing until it reaches tail
◦ Simultaneously, size will keep on reducing until 0 (Empty!)
◦ At this point: set both front & tail to 0 at next enqueue() 17
Initial look at our Queue implementation
● Let us call our class Queue1
● It will store String values for simplicity
public class Queue1{
// instance variable
private String[] queue; // to hold elements
private int front; // indexes front element
private int tail; // indexes tail element
// Rest of methods - to be added as we build the class
}

18
Let us now writing Queue methods
i. Constructor
● Creates an array of a specified size
● Set queue spaces to size of the array
● Initialises both front & tail to -1 // for empty queue
public Queue1(int n){
queue = new String[n];
front = -1;
tail = -1;
}
19
ii. size()
• Returns number of elements in a Queue
• Take-home: Loop from the head to tail node, count
nodes individually!

public int size(){


// …place your code here!
}

20
iii. isEmpty()
• Checks if Queue has elements or not
• Method MUST be invoked before removing, peeking
& printing items,

public boolean isEmpty(){


return size() == 0;
}

21
iv. isFull()
• Checks if the Queue is full
• Needed because we are using an array (Rem: fixed
size?)
• MUST be invoked before adding elements

public boolean isFull(){


return size() == queue.length; //all array slots occupied
}
22
v. enqueue()
• Adds an element to the queue, at the back
• Rem: we cannot enqueue when Queue is full!

public void enqueue(String elem) { if (isEmpty())


if (isFull()){ front = tail = 0; // 1st index
System.out.println(“Queue else
is full."); tail++; // advance tail
} queue[tail] = elem; // store
else {
}
} 23
vi. dequeue()
• Removes & returns element from front
• Rem: Queue MUST have some elements!
public String dequeue() { else {
if (isEmpty()) { String ele = queue[front];
System.out.printf("Queue front++;
empty! \n"); return ele;
return null; }
} }

24
vii. peek()
• Returns element in front, or null if there is none
public String peek(){
if (!isEmpty())
return queue[front];
else
return null; // Queue empty (no front element)
}

25
viii. search()
• Accepts a String value, and returns true when found,
and false otherwise
public boolean search(String key) { if (queue[i].equals(key))
if (isEmpty()) return true;
System.out.println(“Empty."); i++;
else { } //while
int i=0; } //else
while (i<n) { return false;
}
26
Incomplete sample tester class
Queue1 q= new Queue1(4); q.dequeue(); // remove elements
// add elements q.dequeue();
q.enqueue(“CSI247”); q.dequeue();
e.enqueue(“CSI243”); System.out.println(“Size: ”+ q.size());
q.enqueue(“CSI262”); // search
q.enqueue(“CSI142”); System.out.println(“Found: ”+
System.out.println(q1.size()); q.search(“CSI247”));
System.out.println(q1.isEmpty());
q1.enqueue("CSI141");
System.out.println(q1.size());
System.out.println(q1.peek());

27
Exercise 2
a) Type all code segments provided into a Java file
b) Compile the program.
• Fix errors, if any
c) Implement a tester class and test all methods
implemented in Queue class
d) Implement an array-based Queue that works with data
of any valid data type
• Generics!!

28
b) Implementing Queue using a Linked List
● Rem:
• LinkedList is a collection of Nodes
• Always create a Node before inserting new element!
• With LinkedList, there is no:
• Size restriction: List grows and shrinks dynamically
• Queue capacity
• isFull()
• As a queue:
• Insert: At the tail
• Remove: At the front
29
LinkedList Queue implementation
● Let us call our class Queue2
● It will store String values for simplicity
public class Queue2{
private class Node {
// … Node instance variables
// … Node methods
}
// … Queue2 instance variables
// … Queue2 methods
}
30
● Node class
• Rem: LinkedList keeps Nodes
• We need this inner class!
private class Node{
String data; // node's data part
Node next; // a pointer to next node in the Queue
Node(String data) {
this.data = data;
this.next = null; // the last Node in the list
}
} 31
● Queue class
• Common Queue operations (methods) to implement:
• enqueue(): inserts an element (back)
• dequeue(): removes an element (front)
• peek(): returns the element in front of queue
• Item is NOT removed!!!
• isEmpty(): Checks if queue has elements
• Cannot dequeue if empty!
• isFull(): Checks if queue is full
• size(): returns length of the queue
• search(): checks existence of some item in the queue
32
i. Instance variables (For storing data)
public Node front; // tracks front node
public Node tail; // tracks last node

ii. Constructor (For creating an empty Queue2 object)


public Queue2(){
front = null; // Initially, queue is empty!
tail = null;
}
33
Initial look at our implementation
public class Queue2{
private class Node{
String data; // node's data part
Node next; // a pointer to next node in the Stack
Node(String data) {
this.data = data;
this.next = null; // assumption: it will be the last Node
} }
// instance variables
public Node front; // keeps track of front node
public Node tail; // keeps track of last node
// Methods to be added incrementally as we go along
}
34
Writing Queue methods
i. Constructor
• For creating an empty LinkedListQueue object

public Queue2(){
// Initially, queue has no Nodes
front = null;
tail = null;
}

35
ii. size()
• Returns number of nodes in the Queue
public int size(){
// add code to count nodes here!
}

iii. isEmpty()
• Checks if Queue has elements or not
public boolean isEmpty(){
return size() == 0;
} 36
iv. enqueue()
• Add an element to the Queue

public void enqueue(String data) {


Node oldTail = tail;
tail = new Node(data); // new tail Node
if (isEmpty())
front = tail; // It’s a 1st Node
else
oldTail.next = tail; // link new node to old tail node
}
37
v. dequeue()
• Removes element from queue & and returns it
public String dequeue() {
String data = front.data;
front = front.next; // promote next Node to front
if (isEmpty())
tail = null; // no last Node
return data;
}
38
vi. peek()
• Returns front element in the Queue
• Does not delete it!
public String peek() {
if (!isEmpty())) // can’t read from empty Queue
return front.data;
else
return null; // No element in the queue
}
39
vii. printQueue()
• For printing all elements in the queue (Rem: FIFO!)
public void printQueue(){
if (!isEmpty()){
Node currentNode = front; // start from front
while (currentNode != null){
System.out.print(currentNode.data + " ");
currentNode = currentNode.next; // advance to next
}
}
} 40
Incomplete sample tester class

Queue2 que = new Queue2(); que.dequeue(); // remove elements


// add elements que.dequeue();
que.enqueue(“CSI247”); que.dequeue();
que.enqueue(“CSI243”); System.out.println(“Queue size:
“+ que.size());
que.enqueue(“CSI261”); // print
que.enqueue(“CSI141”); que.printQueue();
que.enqueue(“CSI142”); // Implement these new methods in
System.out.println("Front has: Queue2.java
" + que.peek()); getFront(); // returns front element
que.enqueue(“CSI392”); getTail(); // returns tail element

41
Exercises
a) Type all code segments provided into a Java file
b) Compile it.
• Fix errors, if any
c) Implement a tester class and test all the methods
d) Implement a generic LinkedList-based Queue class
e) Implement a tester class to test methods implemented in
d) above, using UB student names
f) Implement another tester class to test methods
implemented in d) above, using Dog class objects
42
Next lesson …

None – the end of the course

43
Q &A

1644

You might also like