1 programming ii
TRANSCRIPT
Linked Lists
u Introduction
u Linked List Abstract Data Type
u General Implementation of the ListADT
u Practice Examples
u Iterators
u Practice Example
u Keep in Mind
2
Introduction: General Linked List
u This chapter introduces how to:u Declare the Abstract Data Type (ADT) Linked List
uDefine the most commonly Operations for General Linked Lists
u Implement a General Linked List
u The basic Linked List consists of a collection of connected, dynamically allocated nodes or items of the same type.
3
linkedList
18
item next
-5
item next
null
78
item next
10
item next
Introduction: General Linked List 4
18linkedList
item next
-5item next
null78item next
10item next
u A linked list contains a collection of data items of the same type that are stored in different objects referred as nodes
u Each node consists of two fields:u A data item field : stores or refers to the data value
u A reference to an object of the same typeu This reference is used to connect to the next node in the list
node
data item Reference to the next node in the list
Introduction: General Linked List 5
18linkedList
item next
-5item next
null78item next
10item next
public class LinkedNode<T>{// Fieldsprivate T item; // item data field of any type Tprivate LinkedNode<T> next; // reference to the next node in the list// Constructors
...// Methods
...} // end generic class LinkedNode
node
data item Reference to the next node in the list
Linked List Abstract Data Typepublic interface ListADT<T> {
// List of Operationspublic void add(T newObject);public void add(int index, T newObject);public boolean contains(T findObject);public boolean isEmpty();public int size();public int indexOf(T findObject);public T get(int index);public T remove(int index);
} // end ListADT generic interface
6
T refers to AnyType
Implementation of the ListADT/*** LinkedList class represents a reference-based implementation of ADT list.* @author <author>*/public class LinkedList<T> implements ListADT<T> {private LinkedNode<T> head; // entry point reference to linked list of items of type<T>public LinkedList() {
head = null;} // end default constructor
/*** TODO Implementation of the interface ListADT declared methods*/
} // end LinkedList class
7
Implementation of the ListADTpublic void add(T newObject); // inserts newObject at the end of the linked list
8
1. Create a NewNode that contains newObject as item fieldI
2. If the list is empty, insert the newNode at the head of the list
3. Otherwise, insert the newNode at the end of the list
Implementation of the ListADTpublic void add(T newObject); // inserts newObject at the end of the linked list
9
head:
35
item next
newNode:
The list is empty
Implementation of the ListADTpublic void add(T newObject); // inserts newObject at the end of the linked list
10
head: 35item next
newNode:
The list is empty
Implementation of the ListADTpublic void add(T newObject); // inserts newObject at the end of the linked list
11
head: 35item next
newNode:
The list is empty(summary diagram)
head:
1
2
3
Implementation of the ListADTpublic void add(T newObject); // inserts newObject at the end of the linked list
12
18head: -5 78 10
35item next
newNode:
runner:
runner: a pointer of type LinkedNode<T> used to traverse the list
List is not empty
newObject:
Implementation of the ListADTpublic void add(T newObject); // inserts newObject at the end of the linked list
13
18head: -5 78 10
35item next
newNode:
runner:
List is not empty
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADTpublic void add(T newObject); // inserts newObject at the end of the linked list
14
18head: -5 78 10
35item next
newNode:
runner:
List is not empty
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADTpublic void add(T newObject); // inserts newObject at the end of the linked list
15
18head: -5 78 10
35item next
newNode:
runner:
List is not empty
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADTpublic void add(T newObject); // inserts newObject at the end of the linked list
16
18head: -5 78 10
35item next
newNode:
runner:
List is not empty
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADTpublic void add(T newObject); // inserts newObject at the end of the linked list
17
18head: -5 78 10 35item next
newNode:
runner:
List is not empty
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADTpublic void add(T newObject); // inserts newObject at the end of the linked list
18
18head: -5 78 10
35item next
newNode:
runner:1
Traverse the list2
3
3
The list is not empty(summary diagram)
runner: a pointer of type LinkedNode<T> used to traverse the list
public void add(int index, T newObject);
19Implementation of the ListADT
Precondition: 0 ≤ index ≤ list.size()
• If index < 0 or index > size() à error (throw an exception or display an error message)
• Otherwise, create a newNode (instance of LinkedNode) that contains the newObject as item data field
• If index == 0 à insert the newNode at the head of the list
• If index == size() à insert the newNode at the end of the list
• If index > 0 and index < size() à insert newNode in the middle of the list at the index position
public void add(int index, T newObject);
20Implementation of the ListADT
18head: -5 78 10 35item next
Case3: 0 < index < list.size()
0 1 2 3 4indices:
-3Index: 3
runner: item next
newNode:
runner initialized to head : a pointer of type LinkedNode<T> used to traverse the listinx an integer initialized to 0 : the index of the node pointed by runner in the list
inx = 0 inx = 1
public void add(int index, T newObject);
21Implementation of the ListADT
18head: -5 78 10 35item next
0 1 2 3 4indices:
-3Index: 3
runner: item next
newNode:
Case3: 0 < index < list.size()
runner initialized to head : a pointer of type LinkedNode<T> used to traverse the listinx an integer initialized to 0 : the index of the node pointed by runner in the list
inx = 1 inx = 2
public void add(int index, T newObject);
22Implementation of the ListADT
18head: -5 78 10 35item next
0 1 2 3 4indices:
Index: 3
runner: item next
newNode:
X
-3
Case3: 0 < index < list.size()
runner initialized to head : a pointer of type LinkedNode<T> used to traverse the listinx an integer initialized to 0 : the index of the node pointed by runner in the list
inx = 2
inx == index -1
public void add(int index, T newObject);
23Implementation of the ListADT
18head: -5 78 10 35item next
runner initialized to head : a pointer of type LinkedNode<T> used to traverse the listinx an integer initialized to 0 : the index of the node pointed by runner in the list
0 1 2 3 4indices:
Index: 3
runner: item next
newNode:
X
-3
Case3: 0 < index < list.size() Summary Diagram
1
Traverse the list until inx = index -1 2
3
4
4inx = 2
public void add(int index, T newObject);
24Implementation of the ListADT
18head: -5 78 10 35item next
0 1 2 3 4 5indices:
Index: 3runner:newNode:
-3
Case3: 0 < index < list.size()
runner initialized to head : a pointer of type LinkedNode<T> used to traverse the listinx an integer initialized to 0 : the index of the node pointed by runner in the list
public boolean contains(T findObject);
25Implementation of the ListADT
• If the list is empty return false
• Otherwise (list is not empty)
• define a runner (a reference to a LinkedNode object) to traverse the list and look for the first node whose data item matches with findObject
• initialize runner to the head of the list
• traverse the list looking for a much with findObject
• while runner != null && there is no match go to the next node in the list
• if the findObject is found return true
• if the list is entirely traversed without finding a match, return false
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADT 26
18head: -5 10 78 10item next
10
runner:
is runner.getItem().equals(findObject)?findObject:
List not empty
No
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADT 27
18head: -5 10 78 10item next
10
runner:
is runner.getItem().equals(findObject)?
findObject:
List not empty
Yesreturn true
Example
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADTpublic int indexOf(T findObject);
28
• Initialize index of type int to -1• if list is empty return index• Otherwise
• define a runner (a reference to a LinkedNode object) to traverse the list and look for the first node whose data item matches with findObject
• initialize runner to the head of the list and increment index
• traverse the list looking for a much with findObject
while runner!= null && there is no match go to the next node in the list and increment index
• if the findObject is found return index
• if the list is entirely traversed without finding a match, return -1
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADTpublic T get(int index);
29
• if index < 0 or index > size() à error (throw an exception or return null)• Otherwise if the list is empty return null
• Otherwise (list is not empty and index in the range of the list indices)
• define a runner (a reference to a LinkedNode object) to traverse the list looking for the node of index “index”
• initialize runner to the head of the list and inx of type int to 0
• while inx < index go to the next node in the list (runner = runner.getNext()) and increment inx
• return runner.getItem()
Precondition: 0 ≤ index < list.size()
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADTpublic T remove(int index);
30
• if index < 0 or index > size() à error (throw an exception or return null)• Otherwise if the list is empty return null
• Otherwise (list is not empty and index in the range of the list indices)
• We distinguish between three cases
• Case1: index == 0 : return the item at the head of the list, then remove the node at the head
• Case2: index == size() – 1: return the item at the tail (end) of the list and remove that node from the list
• Case3: Index > 0 and index < size() -1 : (remove a node from the middle of the list) return the item of the node at index position and remove the latter
Precondition: 0 ≤ index < list.size()
Implementation of the ListADTpublic T remove(int index);
31
Case1: List not empty and index == 0 : remove the node at the head of the list
18head: -5 78 10 35
1
item = head.getItem();
item: 18
2
head = head.getnext();
1
head:
X2
2
3
return item
remove the node at the head of the list
Implementation of the ListADTpublic T remove(int index);
32
Case2: List not empty and index > 0 and index == size -1 : remove the node at the end (tail) of the list
18head: -5 78 10 35
To remove a node from the end of a list, we need a pointer to its previous node• Use a runner to reach the node of index size -2
• Initialize runner to head and inx of type int to 0• While inx < index – 1, go to the next node (runner = runner.getNext()) and increment
inx• item = runner.getNext().getItem();• remove the node at the end of the list: runner.setNext(null);• return item
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADTpublic T remove(int index);
33
18head: -5 78 10 35
runner: a pointer of type LinkedNode<T> used to traverse the list
runner:inx = 0
1
0 1 2 3 4indices:
Index: 4Traverse the list to reach the node of index index-1
runner:inx = 1
2 runner:inx = 2
2 runner:inx = 3
2
2
Get the item at runner.getNext() andRemove runner.getNext()Return item
3
item = runner.getNext().getItem();item: 35
3
X3
Case2: List not empty and index > 0 and index == size -1 : remove the node at the end (tail) of the list
Implementation of the ListADTpublic T remove(int index);
34
Case3: List not empty and index > 0 and index < size -1 : remove a node at the middle of the list
18head: -5 78 10 35
To remove a node from the middle of list (at a given index), we need a pointer to its previous node• Use a runner to reach the node of index index - 1
• Initialize runner to head and inx of type int to 0• While inx < index – 1, go to the next node (runner = runner.getNext()) and increment inx
• item = runner.getNext().getItem();• remove the node at the position index the list: runner.setNext(runner.getNext().getNext());• return item
runner: a pointer of type LinkedNode<T> used to traverse the list
Implementation of the ListADTpublic T remove(int index);
35
18head: -5 78 10 35
runner: a pointer of type LinkedNode<T> used to traverse the list
runner:inx = 0
1
0 1 2 3 4indices:
Index: 2
Traverse the list to reach the node of index index-1
runner:inx = 1
2
2
Get the item at runner.getNext() // remove runner.getNext()runner.setNext(runner.getNext().getNext()) return item
3
item = runner.getNext().getItem();item: 78
3
3X
3
Case3: List not empty and index > 0 and index < size -1 : remove a node at the middle of the list
Implementation of the ListADT
public T remove(int index);
We note that the implementation for Case2 and Case3 is the same.
36
Case3: List not empty and index > 0 and index < size -1 : remove a node at the middle of the list
Case2: List not empty and index > 0 and index == size -1 : remove the node at the end (tail) of the list
Practice Examples
u Declare the ListADT<T> interfaceu Implement the generic LinkedNode<T> classu Implement the linked list of Integers class
u public class LinkedList implements ListADT<Integer>
u Test the implementationu Implement the generic linked list LList<T> class
u public class LinkedList implements ListADT<Integer>
u Test the LList class implementation considering different types T
37
Iterable Interface and Iterators
u Collection<T> Interface
u Iterators
u Iterable Interface
u For-each loop
38
Collection Interfaceu Generic Interface Collection<T>
u The interface Collection<T> specifies methods for performing some basic operations on any collection of objects
public interface Collection<E> implements Iterable {
/* general operations that can be applied to various types of collections containing various types of objects
* to explore the different operations defined in the interface Collection of Java.util, go to: https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html
*/}
39
Traverse a Collection of Objects
u A collection of Objects of type T can beu an array,
u an ArrayList,
u a linkedList,
u etc.
u Need to traverse a collection to print out every item in the collection for instanceu Is there a generic way to do it?
40
Traverse a Collection of Objectsu How to traverse an array of Objects?
u use a for loop to iterate through all the array indices
u How to traverse a singly linked list of Objects?u use a while loop in which you advance a pointer along the list
41
Variety of traversal mechanisms!
How to come up with a single generic method to traverse a collection that works for all kinds of collections that are stored in
wildly different forms?
Generic Way to Traverse a Collection of Objects
The problem is solved by using iterators!
u Iteratoru an object that can be used to traverse a collectionu Iterators are defined by a parameterized interface named Iterator<T>u @see https://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html
u Different types of collections have iterators that are implemented in different ways, but all iterators are used in the same way
u An iterator provides a good way to iterate over a generic set type
42
Iterable interface
u The Iterable interface is a generic interface of java.lang package.public interface Iterable<T>u Iterable interface has one method to override
Iterator<T> interator()returns an iterator over a set of elements of type T
For more details, please visit
https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html
43
For each loop
u An object instance of a class that implements the java.lang.Iterable<T> interface can be target of the “for each” statement
u SyntaxFor (<ElementType> <variable> : <collection>){
<loop boby> // Does not have any effect on the value of <variable> reference
}
u The Iterable interface provides a clean and elegant way to code the iteration functionality
44
Doubly Linked Lists
u The singly linked list does not efficiently support some important operationsu For instance, it is time consuming to go to the end of the list
u Singly linked lists cannot implement “retreat” method which allows one backward move at the time while traversing a list
u A doubly linked list allows bidirectional traversal by storing two links per nodeu Each node now has two links (next and prev)
45
-5node:
prev item next
Doubly linked lists
u Searching and traversing the list can easily be performed in both directions
u Doubly linked lists allowu to move up just as easily as down in the list
u to insert after as well as before a node at a given position (index)
u Insertion (add) and removal (remove) operations involve twice as many link changes as for a singly linked list.
46
18head: -5 78 : tail
Circular Linked List
u In a circularly linked list, the last node’s next link references the first one in the list (i.e. the head of the list)
u The circular list is useful when we want searching to allow wraparound
47
18head: -5 10
Keep in Mindu A linked list represents a collection (that may be empty) of connected, dynamically
allocated nodes (known as linked nodes)
u A linked node of a singly linked list must contain a reference to a node of the same type. This reference is used to connect to the next node in the list
u To add a node at the middle of a singly linked list, we need a reference to the previous nodeu We need a reference to the node at the prior position to the one that we want
to insert
u To remove a node from a singly linked list other than the head of the list, we need a reference to the node prior to the node that we want to remove
u To remove an item or object that we don’t know the index, we can make use of the method indexOf which returns the position (index) of an item in the linked list
48
Keep in Mindu Doubly linked list allows bidirectional traversal of the listu A doubly linked node has two links: a reference to the next node
and a reference to the previous node in the listu Insertion and deletion operations are more easy with doubly
linked lists, but ensure more link changes compared to a singly linked list
u Common error while implementing linked list operations: NullPointerException!u Methods should not be allowed to access fields via a null reference
49