chapter 15 implementing dynamic data structures€¦ · data next data next = null data next java...

23
Java Actually 15: Implementing Dynamic Data Structures 15-1/45 Chapter 15 Implementing Dynamic Data Structures Lecture slides for: Java Actually: A Comprehensive Primer in Programming Khalid Azim Mughal, Torill Hamre, Rolf W. Rasmussen Cengage Learning, 2008. ISBN: 978-1-844480-933-2 http://www.ii.uib.no/~khalid/jac/ Permission is hereby granted to use these lecture slides in conjunction with the book. Modified: 16/2/19 Java Actually 15: Implementing Dynamic Data Structures 15-2/45 Overview Simple Linked Lists: Insertion Deletion Lookup Other Abstract Data Types (ADT): Stack Queues

Upload: others

Post on 18-Jul-2020

9 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-1/45

Chapter 15

Implementing Dynamic Data Structures

Lecture slides for:

Java Actually: A Comprehensive Primer in ProgrammingKhalid Azim Mughal, Torill Hamre, Rolf W. Rasmussen

Cengage Learning, 2008.

ISBN: 978-1-844480-933-2http://www.ii.uib.no/~khalid/jac/

Permission is hereby granted to use these lecture slides in conjunction with the book.

Modified: 16/2/19

Java Actually 15: Implementing Dynamic Data Structures 15-2/45

Overview

Simple Linked Lists:

• Insertion

• Deletion

• Lookup

Other Abstract Data Types (ADT):

• Stack

• Queues

Page 2: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-3/45

Linked lists• A simple linked list is an ordered, linear collection of objects, called nodes.

• A node is an example of an object that has a reference to an object of the same type, i.e., is self-referencing.

• The class Node<E> defines two field variables:– The reference data that refers to any object.– The reference next that refers to a node.

• The nodes can be linked together using the next field to form a linked list.

Java Actually 15: Implementing Dynamic Data Structures 15-4/45

The class Node/** A node holds data and a reference to a node. */public class Node<E> {

/** Data in the node. */ private E data; /** Reference to the next node. */ private Node<E> next;

public Node(E data_obj, Node<E> nodeRef) { this.data = data_obj; this.next = nodeRef; }

public void setData(E obj) { this.data = obj; } public void setNext(Node<E> node) { this.next = node; }

public E getData() { return this.data; } public Node<E> getNext() { return this.next; }}

Page 3: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-5/45

Class diagram for a simple linked list (Figure 16.1)

A concrete linked list for strings

LinkedList Node

E

head

tail

data

next

E

head:Ref(Node<String>)

tail:Ref(Node<String>)

"hail"

:String

"ice"

:String

"snow"

:String

"sleet"

:String

p:Ref(Node<String>)

:LinkedList<String>

data

next

:Node<String>

data

next

:Node<String>

data

next = null

:Node<String>

data

next

:Node<String>

Java Actually 15: Implementing Dynamic Data Structures 15-6/45

• To insert data into and get data from the node:

• Find the node’s successor:

• Set the successor of the node:

• Move the reference p so that it refers to its successor:

String str = head.getData(); // Get data from the first node.

p.setData("frost"); // Data in the node referenced by p is changed to "frost".

Node<String> successor = p.getNext(); // Get successor to p.

p.setNext(q); // q set as successor to p.

p = p.getNext(); // Reference p now refers to its successor.

Page 4: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-7/45

Interface ILinkedListe<E> (Program 16.2, Figure 16.2)

Iterable<E>

«interface»

(a) Implementing linked lists (b) Implementing an iterator for linked lists

ILinkedList<E>

«interface»

LinkedList<E>

Iterator<E>

«interface»

LinkedListIterator<E>

Iterator<E> iterator()

boolean hasNext()

E next()

void remove()

public interface ILinkedList<E> extends Iterable<E> { // Mutators public void insertAtHead(E data_obj); public void insertAtTail(E data_obj); public E removeFromHead(); public E removeFromTail(); boolean remove(E data_obj);

// Selectors public boolean isEmpty(); int numberOfNodes(); Node<E> first(); Node<E> last(); Node<E> find(E data_obj);

// Other methods void listToArray(E[] array);}

Java Actually 15: Implementing Dynamic Data Structures 15-8/45

The class LinkedList<E>

public class LinkedList<E> implements ILinkedList<E> {

/** Head of the list */

private Node<E> head;

/** Tail of the list */

private Node<E> tail;

/** Number of nodes in the list */

private int numberOfNodes;

// ...

}

Page 5: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-9/45

Inserting at the head of a linked list (Program 16.3)

public void insertAtHead(E dataObj) { // (1)

Node<E> p = new Node<E>(dataObj, null);

if (isEmpty()) {

head = tail = p;

} else { // head = new MyNode<>(dataObj, head);

p.setNext(head); // Step 1

head = p; // Step 2

}

numberOfNodes++;

}

• It is important that the two steps are performed in the right order (Figure 16.3).

If the list is empty The head and the tail are set to refer to the new nodeElse Step 1: Set the head to be the successor of the new node Step 2: Set the head to refer to the new node

Java Actually 15: Implementing Dynamic Data Structures 15-10/45

Insert a node at the head of a linked list (Figure 16.4)

Step 1: p.setNext(head);

Step 2: head = p;

(c) Step 2 in inserting at the head of the list

(b) Step 1 in inserting at the head of the list

data = "hail"

next

data = "ice"

next = null

data = "frost"

next

data = "hail"

next

data = "ice"

next = null

data = "frost"

next

p:Ref(Node<String>)

p:Ref(Node<String>)

head:Ref(Node<String>)

tail:Ref(Node<String>) head:Ref(Node<String>)

tail:Ref(Node<String>) :Node<String>

:Node<String>

:Node<String>

:Node<String> :Node<String>

:Node<String>

Page 6: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-11/45

Inserting at the tail of a linked list

public void insertAtTail(E dataObj) { // (2)

Node<E> p = new Node<E>(dataObj, null);

if (isEmpty()) {

head = tail = p;

} else {

tail.setNext(p); // Step 1

tail = p; // Step 2

}

numberOfNodes++;

}

If the list is empty The head and the tail are set to refer to the new nodeElse Step 1: Set the new node as the successor of the tail node Step 2: Set the tail to refer to the new node

Java Actually 15: Implementing Dynamic Data Structures 15-12/45

Insert a node at the tail of a linked list (Figure 16.5b og c)( ) g

Step 1: tail.setNext(p);

(b) Step 1 in inserting at the tail of the list

Step 2: tail = p;

(c) Step 2 in inserting at the tail of the list

data = "hail"

next

data = "ice"

next

data = "hail"

next

data = "ice"

next

data = "frost"

next = null

data = "frost"

next = null

head:Ref(Node<String>)

p:Ref(Node<String>)

head:Ref(Node<String>)

p:Ref(Node<String>)

tail:Ref(Node<String>)

tail:Ref(Node<String>)

:Node<String>

:Node<String> :Node<String>

:Node<String>

:Node<String>

:Node<String>

Page 7: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-13/45

Removing a node from the head of a linked list

public E removeFromHead() { // (3)

assert numberOfNodes > 0 : "The list cannot be empty.";

Node<E> p = head; // Step 1

if (head == tail) {

head = tail = null; // Only one node in the list.

} else {

head = p.getNext(); // Step 2

}

numberOfNodes--;

return p.getData();

}

Step 1: Let p refer to the first node in the list, i.e. same node as the headIf the head and the tail refer to the same node, i.e. only one node in the list

Both the head and the tail are set to nullElse

Step 2: Set the head to refer to the successor of the first node referenced by p

Java Actually 15: Implementing Dynamic Data Structures 15-14/45

Removing a node from the head of a linked list (Figure 16.6b og c)

Step 1: p = head;

Step 2: head = p.getNext();

(b) Step 1 in removing from the head of the list

( ) g

(c) Step 2 in removing from the head of the list

data = "hail"

next

data = "ice"

next = null

data = "hail"

next

data = "ice"

next = null

data = "frost"

next

data = "frost"

next

tail:Ref(Node<String>)

tail:Ref(Node<String>)

head:Ref(Node<String>)

head:Ref(Node<String>)

p:Ref(Node<String>)

p:Ref(Node<String>)

:Node<String> :Node<String>

:Node<String> :Node<String>

:Node<String>

Page 8: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-15/45

Removing a node from the tail of a linked list• We let reference p denote the node to be removed (Figure 16.7, step 1):

• Deleting a node in a list requires knowledge of the predecessor of the node to be deleted.– To find the second last node, we have to traverse the list from the head:

p = tail; // Step 1

Step 1: p = tail;

(b) Step 1 in removing from the tail of the list

data = "hail"

next

data = "ice"

next

data = "frost"

next = null

head:Ref(Node<String>)

p:Ref(Node<String>)

tail:Ref(Node<String>) :Node<String> :Node<String>

:Node<String>

Let nextToLast refer to the first node in the list, i.e. same node as the headRepeat while not arrived at the next-to-last node

Move the reference nextToLast to the successor

Java Actually 15: Implementing Dynamic Data Structures 15-16/45

– Source code to find the second last node (Figure 16.7, step 2):

Node<E> nextToLast = head;while (nextToLast.getNext() != tail) // Arrived at the next-to-last node? nextToLast = nextToLast.getNext(); // Move to the successor.

nextToLast:Ref(Node<String>) Step 2: update nextToLast;

(c) Step 2 in removing from the tail of the list

data = "hail"

next

data = "ice"

next

data = "frost"

next = null

head:Ref(Node<String>)

p:Ref(Node<String>)

tail:Ref(Node<String>)

:Node<String>

:Node<String> :Node<String>

Page 9: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-17/45

Removing a node from the tail of a linked list (Fig. 16.8, steps 3 and 4)

Step 3: tail = nextToLast;

Step 4: tail.setNext(null);

(d) Step 3 in removing from the tail of the list

(e) Step 4 in removing from the tail of the list

data = "hail"

next

data = "ice"

next

data = "hail"

next

data = "ice"

next = null

data = "frost"

next = null

data = "frost"

next = null

head:Ref(Node<String>)

head:Ref(Node<String>)

p:Ref(Node<String>)

p:Ref(Node<String>)

tail:Ref(Node<String>)

tail:Ref(Node<String>)

nextToLast:Ref(Node<String>)

nextToLast:Ref(Node<String>)

:Node<String> :Node<String>

:Node<String>

:Node<String>

:Node<String> :Node<String>

Java Actually 15: Implementing Dynamic Data Structures 15-18/45

public E removeFromTail() { // (4)

assert numberOfNodes > 0 : "The list cannot be empty.";

Node<E> p = tail; // Step 1

if (head == tail) {

head = tail = null; // Only one node in the list.

} else {

Node<E> nextToLast = head; // Step 2

while (nextToLast.getNext() != tail) {

nextToLast = nextToLast.getNext();

}

tail = nextToLast; // Step 3

tail.setNext(null); // Step 4

}

numberOfNodes--;

return p.getData();

}

Page 10: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-19/45

Removing a node from inside a linked list• Find the node to be deleted and its predecessor (step 1):

• Source code to find the node to be deleted and its predecessor:

Repeat while the end of the list not reached and the node to be removed not foundIf the current node is the one to be removed

The node is found, and thereby its predecessorElse

Move the reference for the current node and for the predecessor

Node<E> currentNode = head;Node<E> predecessor = null;boolean found = false;while (currentNode != null && !found) { if (currentNode.getData().equals(dataObj)) { found = true; } else { // Not yet found. Update predecessor and currentNode references. predecessor = currentNode; // (1) currentNode = currentNode.getNext(); // (2) }}

Java Actually 15: Implementing Dynamic Data Structures 15-20/45

Removing a node from inside a linked list (Figure 16.9, step 1)

(a) Before removing a node from inside the list

Step 1: Find node that is to be deleted, and its predecessor;

(b) Step 1 in removing a node from inside the list

data = "hail"

next

data = "snow"

next

data = "sleet"

next = null

data = "ice"

next

data = "hail"

next

data = "snow"

next

data = "sleet"

next = null

data = "ice"

next

currentNode:Ref(Node<String>) predecessor:Ref(Node<String>)

:Node<String> :Node<String> :Node<String> :Node<String>

:Node<String> :Node<String> :Node<String> :Node<String>

head:Ref(Node<String>)

head:Ref(Node<String>)

tail:Ref(Node<String>)

tail:Ref(Node<String>)

Page 11: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-21/45

• There are three possibilities to consider in order to delete a node that exists in the list:– The node is the first node in the list (predecessor == null).

The method removeFromHead() is called to delete it.

– The node is the last node in the list (currentNode.getNext () == null).The tail and the last node are updated:

tail = predecessor; tail.setNext(null);

– Node is inside the list.The successor to the node to be deleted is now the successor to its predecessor (step 2):

predecessor.setNext(currentNode.getNext());

Java Actually 15: Implementing Dynamic Data Structures 15-22/45

Removing a node from inside a linked list (Figure 16.9, step 2)

(c) Step 2 in removing a node from inside the list

Step 2: predecessor.setNext(currentNode.getNext());

currentNode:Ref(Node<String>)

data = "hail"

next

data = "snow"

next

data = "sleet"

next = null

data = "ice"

next

predecessor:Ref(Node<String>)

:Node<String> :Node<String> :Node<String> :Node<String>

head:Ref(Node<String>) tail:Ref(Node<String>)

Page 12: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-23/45

Finding data in a linked list• The method uses the equals() method to compare objects in the list.

• The method returns the node that contains the object to be found.

public Node<E> find(E dataObj) {

// Traverse the list, starting from the head.

Node<E> currentNode = head;

while (currentNode != null) {

if (currentNode.getData().equals(dataObj)) {

return currentNode; // Found.

}

currentNode = currentNode.getNext();

}

return null; // Not found.

}

Java Actually 15: Implementing Dynamic Data Structures 15-24/45

Iterator for a linked list.• The class LinkedList<E> implements the contract ILinkedList<E>, and thus also

indirectly the contract Iterable<E> (See Figure 16.3).

• The class LinkedListIterator implements an iterator for the class LinkedList:public class LinkedListIterator<E> implements Iterator<E> { private Node<E> currentNode;

public LinkedListIterator(ILinkedList<E> list) { currentNode = list.first(); }

public boolean hasNext() { return currentNode != null; }

public E next() { E data = currentNode.getData(); currentNode = currentNode.getNext(); return data; }

public void remove() { throw new UnsupportedOperationException(); }}

Page 13: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-25/45

Convert a linked list to an array• The method fills the specified array with elements from the list.

public void listToArray(E[] toArray) { // (7)

assert toArray.length == numberOfNodes : "Wrong size of array.";

int i = 0;

for (E data : this) {

toArray[i++] = data;

}

}

Java Actually 15: Implementing Dynamic Data Structures 15-26/45

Example: Convert a linked list to an array

public class ListToArrayDemo { public static void main(String[] args) { LinkedList<Character> lst = new LinkedList<Character>(); lst.insertAtHead('a'); lst.insertAtHead('b'); lst.insertAtHead('B'); lst.insertAtHead('A'); for (char c : lst) { System.out.print(c); } System.out.println(); Character[] array = new Character[lst.numberOfNodes()]; lst.listToArray(array); System.out.println(array.length); for (char c : array) { System.out.print(c); } System.out.println(); }

Page 14: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-27/45

// ...}

Java Actually 15: Implementing Dynamic Data Structures 15-28/45

Data can be shared among linked lists

data

next

:Node

data

next

:Node

data

next

:Node

data

next

:Node

Name: headType: ref(Node)

Name: tailType: ref(Node)

:…

Name: pType: ref(Node)

data

next

:Node

data

next

:Node

data

next

:Node

Name: headType: ref(Node)

Name: tailType: ref(Node)

list1:

list2:

:… :…:…

Page 15: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-29/45

ADT: Stack• A stack is a LIFO (Last-In, First-Out) data structure (Figure 16.10).

stack

"snow"

"sleet"

"ice"

push(element) pop()

peek()tos or top-of-stack

Java Actually 15: Implementing Dynamic Data Structures 15-30/45

Stack operationsStack operation Description

push(element) Add the element to top of the stack.

pop() Removes and returns the first element on the top of the stack.

peek() Returns the first element on the top of the stack without removing it from the stack.

isEmpty() Returns true or false depending on whether the stack is empty or not.

Page 16: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-31/45

Stack Implementation by aggregation• Stack operations are delegated to the linked list operations.

• In this implementation a client can not break the abstraction that a stack represents.

• The class java.util.Stack<E> provides another implementation of stacks.

class StackByAggregation<E> {

// Field

private LinkedList<E> stackList; // (1)

// Constructor

public StackByAggregation() { // (2)

stackList = new LinkedList<E>();

}

// Instance methods

public void push(E data) { // (3)

stackList.insertAtHead(data);

}

Java Actually 15: Implementing Dynamic Data Structures 15-32/45

public E pop() { // (4)

if (empty())

return null;

return stackList.removeFromHead();

}

public E peek() { // (5)

if (empty())

return null;

return stackList.first().getData();

}

public boolean empty() { // (6)

return stackList.isEmpty();

}

}

Page 17: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-33/45

A client that uses a stack (StackClient.java)

public class StackClient {

public static void main(String[] args) {

// (1) Check if there are program arguments:

if (args.length == 0) {

System.out.println("Usage: java StackClient <argument list>");

return;

}

// (2) Create a stack:

StackByAggregation<String> stack = new StackByAggregation<>();

// (3) Push all program arguments (strings) on to the stack:

for (int i = 0; i < args.length; i++)

stack.push(args[i]);

// (4) Pop all elements from the stack:

while (!stack.empty())

System.out.print(stack.pop().toLowerCase() + " ");

System.out.println();

}

}

Java Actually 15: Implementing Dynamic Data Structures 15-34/45

Running the program:>java StackClient Tall STACKS topple easily

easily topple stacks tall

Page 18: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-35/45

Using stacks• We will look at a problem from graph theory.

• A graph has nodes and edges connecting the nodes together.– The edges are directed, meaning that they have an arrowheads at one end.– One can navigate from one node to another in the specified direction.

Java Actually 15: Implementing Dynamic Data Structures 15-36/45

Graphs• Each node is a city (which has a number specified in the node)

• An edge from one city indicates which city can be accessed directly from this city.

(b ) Graph array

T:true F:false

[3] [4][0] [1] [2]

[0]

[1]

[2]

TF F

F F

T T

F FT

F F F F T

F T T F F

F F F F F

[3]

[4]

(a ) Graph

0

4

3 2

1

node

edge

Page 19: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-37/45

The Problem• Which cities can be reached from a given city?

– We may, for example, reach the cities with the numbers 1, 2 and 4 by starting in city number 3

– We can step-wise find the cities that can be accessed directly from a city, and repeat the same process for these cities.

• The process uses a stack and a set.– The stack keeps track of which cities we have not as yet checked to reach other

cities directly.– The set keeps track of cities that have been reached so far in the process.– Each step in the process involves the following:

Pop the city from the top of the stackIf this city is not in the set

Add this city to the setPush all cities that can be reached directly from this city on to the stack

Java Actually 15: Implementing Dynamic Data Structures 15-38/45

Step to find the cities that are reachable from city number 3

Step no. Stack Set 1. <3> []

2. <1, 2> [3]

3. <1, 4> [3, 2]

4. <1> [3, 2, 4]

5. <2> [3, 2, 4, 1]

6. <> [3, 2, 4, 1]

Page 20: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-39/45

Example: Graphimport java.util.HashSet;

import java.util.Scanner;

import java.util.Set;

public class StackClient2 {

public static void main(String[] args) {

// (1) Create a city graph:

boolean[][] cityGraph = {

{false, true, false, true, true},

{false, false, true, false, false},

{false, false, false, false, true},

{false, true, true, false, false},

{false, false, false, false, false}

};

// (2) Read the city from the keyboard:

System.out.print("Type the number of the city to start from [0-" +

(cityGraph.length-1) + "]: ");

Java Actually 15: Implementing Dynamic Data Structures 15-40/45

Scanner keyboard = new Scanner(System.in);

int startCityNum = keyboard.nextInt();

if (startCityNum < 0 || startCityNum >= cityGraph.length) {

System.out.print("Unknown city number: " + startCityNum);

return;

}

// (3) Create a city stack:

StackByAggregation<Integer> cityStack = new StackByAggregation<>();

// (4) Create a city set:

Set<Integer> citySet = new HashSet<>();

// (5) Push start city on the stack:

cityStack.push(startCityNum);

// (6) Handle each city found on the stack:

while (!cityStack.empty()) {

// Pop current city from the stack.

int currentCityNum = cityStack.pop();

// Check if the city has already been handled.

if (!citySet.contains(currentCityNum)) {

Page 21: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-41/45

// Insert current city to the city set.

citySet.add(currentCityNum);

// Push all cities that can be reached directly from

// the current city on to the stack

for (int j = 0; j < cityGraph[currentCityNum].length; j++) {

if (cityGraph[currentCityNum][j])

cityStack.push(j);

}

}

}

// Remove start city from the city set, and print the city stack.

citySet.remove(startCityNum);

System.out.print("From city no. " + startCityNum +

", the following cities can be reached: " + citySet);

}

}

Running the program:>java StackClient2

Type the number of the city to start from [0-4]: 3

From city no. 3, the following cities can be reached: [1, 2, 4]

Java Actually 15: Implementing Dynamic Data Structures 15-42/45

ADT: Queues• A queue is a FIFO (First-In, First-Out) data structure (Figure 16.13).

Queue operationsQueue operation Description

enqueue(element) Adds the element to the back of the queue.

dequeue() Removes and returns the first element in queue.

peek() Returns the first element in the queue without removing it from the queue.

isEmpty() Returns true or false depending on whether the queue is empty or not.

enqueue(element) dequeue()

peek()

"snow""sleet""ice"

Page 22: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-43/45

Queue implementation by inheritance• Since we have used inheritance, a client can break the abstraction a queue represents.

class QueueByInheritance<E> extends LinkedList<E> {

public void enqueue(E data) { // (1) insertAtTail(data); } public E dequeue() { // (2) if (empty()) return null; return removeFromHead(); } public E peek() { // (3) if (empty()) return null; return first().getData(); } public boolean empty() { // (4) return isEmpty(); }}

Java Actually 15: Implementing Dynamic Data Structures 15-44/45

Client using a Queue (QueueClient.java)

public class QueueClient {

public static void main(String[] args) {

// (1) Check if there are any program arguments:

if (args.length == 0) {

System.out.println("Usage: java QueueClient <argument list>");

return;

}

// (2) Create a queue:

QueueByInheritance<String> queue = new QueueByInheritance<>();

// (3) Enqueue all the program arguments (strings):

for (int i = 0; i < args.length; i++)

queue.enqueue(args[i]);

// (4) Dequeue the queue for all elements:

while (!queue.empty())

System.out.print(queue.dequeue().toUpperCase() + " ");

System.out.println();

Page 23: Chapter 15 Implementing Dynamic Data Structures€¦ · data next data next = null data next Java Actually 15: Implementing Dynamic Data Structures 15-6/45 † To insert data into

Java Actually 15: Implementing Dynamic Data Structures 15-45/45

// (5) Can call methods that queues inherit and break

// the queue abstraction:

for (int i = 0; i < args.length; i++)

queue.insertAtHead(args[i]);

// (6) Print the queue elements:

while (!queue.empty())

System.out.print(queue.dequeue().toUpperCase() + " ");

System.out.println();

}

}

Running the program:>java QueueClient You are now number two in the queue

YOU ARE NOW NUMBER TWO IN THE QUEUE

QUEUE THE IN TWO NUMBER NOW ARE YOU