Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
Linked Lists
u Introduction
u Linked List Abstract Data Type
u SinglyLinkedList Implementation of the ListADT
u ArrayList Implementation of the ListADT
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
LinkedNode 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<T>() {
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 data field
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 (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 (list is not empty and index in the range of the list indices)
• We distinguish two cases
• Case1: index == 0 : return the item at the head of the list, then remove the node at the head
• Case2: Index > 0 and index <= size() -1 : remove the item stored at index position of the list and return it
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
Case3: List not empty and index > 0 and index <= size -1 : remove a node other than the head
18head: -5 78 10 35
To remove a node from the list (at a given index not zero), 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);
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: (Example) 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
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
Case2 (general case): List not empty and index > 0 and index <= size -1 : remove a node at the middle 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 SinglyLinkedList<T> class
u public class SinglyLinkedList<T> implements ListADT<T>u Test the SinglyLinkedList class implementation considering different types
Tu Implement the generic class ArrayList<T> implements ListADT<T>
35
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)
36
-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.
37
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
38
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
39
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
40