2. Learning Outcomes
After the completion of this section, students
should be able to:
Write a class which implements a simple list-like abstract
data type
Explain the differences between arrays and linked lists
Write proper code to manipulate linked list in Java
Understand the doubly linked-list data structure
2
2
3. Lecture Scope
Lists
Arrays
Linked Lists
Singly Linked List
Doubly Linked List
Linked Lists Analysis (Complexity Analysis)
With Singly Linked List
With Doubly Linked List
3
3
4. List Definition
List – A sequence of elements in certain linear
order
[English] List is where you put what to do one by
one in sequence
Example: Shopping list
4
6. Basic Operations [English]
Traversing – Where you navigate your shopping list one
by one
Searching/Retrieving – Where you starting to find out
specific items that you want to buy in your shopping list
Inserting – Insert new stuff to buy in your shopping list
Removing/Deleting – Where you strike out the things
that you have bought
6
8. 8
Imagine that we have 100 scores. We need to read them, process
them and print them.
We must also keep these 100 scores in memory for the duration of
the program.
We can define a hundred variables, each with a different name, as
shown below
Arrays
9. 9
But having 100 different names creates other problems. We need
100 references to read them, 100 references to process them and
100 references to write them. The following Figure shows a diagram
that illustrates this problem.
Arrays (cont…)
10. 10
An array is a sequenced collection of elements, normally of the
same data type, although some programming languages accept
arrays in which elements are of different types. We can refer to
the elements in the array as the first element, the second element
and so forth, until we get to the last element.
Arrays (cont…)
11. Declared using [ ] operator
1- datatype[] arrayRefVar;
Example:
double[] myList;
OR
2- datatype arrayRefVar[]; // This style is allowed
Example:
double myList[];
Arrays (Declaration)
11
12. In the definition:
int [ ] tests;
tests = new int[SIZE]; // SIZE is 5
allocates the following memory
first
element
second
element
third
element
fourth
element
fifth
element
12
Arrays (Storage in Memory)
13. In the definition:
int [ ] tests;
tests = new int[ISIZE];
int is the data type of the array elements
tests is the name of the array
ISIZE, in [ISIZE], is the size declarator. It shows the number
of elements in the array.
The size of an array is the number of bytes allocated for it
(number of elements) * (bytes needed for each element)
13
Arrays (Terminology)
14. Array Terminology Examples The Length of an Array
Once an array is created, its
size is fixed. It cannot be
changed. You can find its size
using
arrayRefVar.length
For example,
myList.length //returns 10
14
Arrays (Terminology) (cont…)
15. Each array element has a subscript (index), used to
access the element.
Subscripts (index) start at 0
15
Arrays (Accessing Array Elements)
0 1 2 3 4
Subscripts
(index)
16. public class Test {
public static void main(String[] args)
{
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}
After the array is created
0
1
2
3
4
0
0
0
0
0
After the first iteration
0
1
2
3
4
0
1
0
0
0
16
Arrays (Example)
17. 17
The arrays discussed so far are known as one-dimensional arrays
because the data is organized linearly in only one direction.
Many applications require that data be stored in more than one
dimension. The Figure below shows a table, which is commonly called
a two-dimensional array.
Multi-Dimensional Arrays
19. 19
Although we can apply conventional operations defined for each element of
an array, there are some operations that we can define on an array as a data
structure.
The common operations on arrays as structures are searching, insertion,
deletion, retrieval and traversal.
Although searching, retrieval and traversal of an array is an easy job,
insertion and deletion is time consuming.
The elements need to be shifted down before insertion and shifted up after
deletion.
An array is a suitable structure when a small number of insertions and
deletions are required, but a lot of searching and retrieval is needed.
Operations on Array
20. 20
The following algorithm gives an example of finding the average of elements
in array whose elements are reals.
Operations on Array (cont…)
21. Pros:
Fast element access
Cons:
While many applications require resizing, static arrays
are impossible to resize
Required size is not always immediately available
Arrays: The Pros & Cons
21
23. Introduction
Storing data items in arrays has at least two limitations
The array size is fixed once it is created: Changing the size of
the array requires creating a new array ad then copying all data
from the old array to the new array
The data items in the array are next to each other in memory:
Inserting an item inside the array requires shifting other items
A linked structure is introduced to overcome limitations of
arrays and allow easy insertion and deletion
23
23
24. Introduction (cont.)
A linked structure is introduced to overcome limitations of
arrays and allow easy insertion and deletion
A collection of nodes storing data items and links to other nodes
If each node has a data field and a reference field to another
node called next or successor, the sequence of nodes is referred
to as a singly linked list
Nodes can be located anywhere in the memory
The first node is called head and the last node is called tail
24
24
25. Linked Structures
An alternative to array-based implementations are linked structures
A linked structure uses object references to create links between
objects
Recall that an object reference variable holds the address of an
object
25
25
26. Linked Lists are dynamic data structures that grow and shrink one
element at a time, normally without some of the inefficiencies of
arrays.
A linked list is a series of connected nodes
We create a new node every time we add something to the List and
we remove nodes when item removed from list and reclaim memory
A
Head
B C
Linked Lists
26
27. Each node contains at least
1. A piece of data (any type)
2. Pointer to the next node in the list
head : pointer to the first node
Sometimes called front, first
The last node points to NULL
A
data pointer
node
Linked Lists (cont…)
27
class Node {
Integer data;
Node next = null;
Node(int val) {
data = val
}
}
27
28. Linked list can be Singly-Linked or Doubly-Linked
Variations of Linked Lists
28
29. A doubly
linked list
contains next
and previous
members
A single
linked list
contains only
a next
member.
29
Variations of Linked Lists (cont…)
29
30. Circular linked lists
The last node points to the first node of the list
How do we know when we have finished traversing the
list? (Tip: check if the pointer of the current node is
equal to the head.)
A
Head
B C
Variations of Linked Lists (cont…)
30
31. 2 8 3 5
Circular singly linked list
2 8 3
5
list
list
Circular doubly linked list
Variations of Linked Lists (cont…)
Circular linked lists
31
32. A singly linked list is a concrete
data structure consisting of a
sequence of nodes
Each node stores
element
link to the next node
next
element node
A B C D
32
Singly Linked Lists
32
33. Singly Linked Lists - Insertion
We can add a node anywhere into the list:
1. Empty List
2. Before head
3. After tail
4. In between
33
34. Insertion (Cases)
Case 1 : Empty List Case
When list is empty, which is indicated by (head == NULL)condition,
the insertion is quite simple. Algorithm sets both head and tail to
point to the new node.
34
35. Insertion (Case)
Case 2 : Add First
In this case, new node is inserted right
before the current head node.
35
36. Insertion (Case)
Case 2 : Add First
1st Step : Update the next link of a new node, to point to the current head
node.
36
37. Insertion (Case)
Case 2 : Add First
2nd Step : Update head link to point to the new node.
37
38. Algorithm addFirst(node)
{
node.next = head // make node point to the old head,
this is also correct when linked list is empty
head = v // make head point to the new node
}
Add First(cont…)
38
39. Insertion (Case)
Case 3 : Add Last
In this case, new node is inserted right
after the current tail node.
39
40. Insertion (Case)
Case 3 : Add Last
1st Step : Update the next link of the current tail
node, to point to the new node.
40
42. Algorithm addLast(node)
{
node.next = null //make the new node node point to null object
tail.next = node //make the old tail node point to the new node
tail = node //make tail point to the new node
//if there is no tail pointer then you have to traverse the
list to the last node
}
Add Last (cont…)
42
42
43. Insertion (Case)
Case 4 : General Case
In general case, new node is always
inserted between two nodes, which are
already in the list. Head and tail links are
not updated in this case.
43
44. Insertion (Case)
Case 4 : General Case
1nd Step : Update link of the new node, to point to the
"next" node.
44
45. Insertion (Case)
Case 4 : General Case
2st Step : Update link of the "previous" node, to point
to the new node.
45
46. Singly Linked List: Deletion
• Deleting a node from a linked list is also
straightforward but there are a few cases we
need to account for:
– The list is empty; or
– The node to remove is the only node in the
linked-list; or
– We are removing the head node; or
– We are removing the tail node; or
– The node to remove is somewhere in between
the head and tail; or
– The item to remove doesn’t exist in the linked-
list 46
47. Singly Linked List: Deletion Algorithm
The algorithm whose cases we have
described will remove a node from
anywhere within a list irrespective of
whether the node is the head, etc.
47
49. A doubly linked list is a concrete data structure
consisting of a sequence of nodes.
Each node stores:
element
link to the previous node
link to the next node
Special trailer and header nodes
prev next
element
trailer
header nodes/positions
elements
node
Doubly Linked Lists
49
49
50. In the Doubly linked lists:
Each node points to the successor and the predecessor
Advantage:
given a node, it is easy to visit its predecessor. Convenient to
traverse lists backwards
5
Head
10
2
B
A C
50
Doubly Linked Lists (cont…)
51. /** Node of a doubly linked list of strings */
public class DNode {
protected String element; // String element stored by a node
protected DNode next, prev; // Pointers to next and previous nodes
/** Constructor that creates a node with given fields */
public DNode(String e, DNode p, DNode n) {
element = e;
prev = p;
next = n; } /** Returns the element of this node */
public String getElement() { return element; } /** Returns the previous node of this node */
public DNode getPrev() { return prev; } /** Returns the next node of this node */
public DNode getNext() { return next; } /** Sets the element of this node */
public void setElement(String newElem) { element = newElem; }
/** Sets the previous node of this node */
public void setPrev(DNode newPrev) { prev = newPrev; }
/** Sets the next node of this node */
public void setNext(DNode newNext) { next = newNext; }
} 51
The Node Class of Doubly Linked List
52. (a) Before the insertion
Rome Seattle New York
Rome Seattle New York
Sydney
(b) After the insertion
header trailer
header trailer
52
Doubly Linked Lists
Inserting at the Head
52
53. (a) Before the insertion
Rome Seattle New York
Seattle Sydney New York
Rome
(b) After the insertion
header trailer
header trailer
53
Doubly Linked Lists
Inserting in the Middle
53
54. Seattle Sydney New York
Rome
(a) Before the deletion
header trailer
Rome Seattle Sydney
header trailer
(b) After the deletion
54
Doubly Linked Lists
Removing at the Tail
54
55. Seattle Sydney New York
Rome
(a) Before the deletion
header trailer
(b) After the deletion
Rome Seattle New York
header trailer
55
Doubly Linked Lists
Removing in the Middle
55
56. 56
A linked list is a very efficient data structure for sorted list that will go through
many insertions and deletions.
A linked list is a dynamic data structure in which the list can start with no
nodes and then grow as new nodes are needed.
A node can be easily deleted without moving other nodes, as would be the
case with an array.
For example, a linked list could be used to hold the records of students in a
school. Each quarter or semester, new students enroll in the school and
some students leave or graduate.
A linked list is a suitable structure if a large number of insertions and deletions
are needed, but searching a linked list is slower that searching an array.
Applications of linked lists
57. Java has a LinkedList class defined as part of the Java
collection framework, which is found in the java.util
package.
So you simply declare an instance of the LinkedList
class and call member methods as required by your
program to manipulate the linked list.
JAVA Built-in LinkedList Class
57
59. 59
Singly Linked Lists Analysis
- Complexity Analysis -
Note: some ideas in this section are repeated in another way, or another
representation way
Both are doing the same operation
59
60. public void append(Object obj){
Element element = new Element(obj, null);
if(head == null)
head = element;
else
tail.next = element;
tail = element;
}
Complexity is O(1)
Singly Linked Lists
Insertion at the End (Append)
60
61. public void prepend(Object obj) {
Element element = new Element(obj, head);
if(head == null)
tail = element;
head = element;
}
Complexity is O(1)
Singly Linked Lists
Insertion at the Beginning (Prepend)
61
62. public void insertBefore(Object obj) {
Element element = new Element(obj, this);
if(this == head) {
head = element;
return;
}
Element previous = head;
while (previous.next != this) {
previous = previous.next;
}
previous.next = element;
}
Complexity is O(n)
public void insertAfter(Object obj) {
next = new Element(obj, next);
if(this == tail)
tail = next;
}
Complexity is O(1)
we can also define insertAfter or InsertBefore for the Element class to
insert a given object after or before a specific a node respectively:
Singly Linked Lists
Insertion Before and After an Element
62
63. To move a reference e from one node to the next:
Example: Count the number of nodes in a linked list.
public int countNodes(){
int count = 0;
Element e = head;
while(e != null){
count++;
e = e.next;
}
return count;
}
e = e.next;
Complexity is O(n)
Singly Linked Lists
Traversal
63
64. To search for an element, we traverse from head until we locate the object.
Example: Count the number of nodes with data field equal to a given
object.
public int countNodes(Object obj){
int count = 0;
Element e = head;
while(e != null){
if(e.data.equals(obj))
count++;
e = e.next;
}
return count;
}
Complexity is O(n)
Singly Linked Lists
Searching
64
65. public void extractFirst() {
if(head == null)
throw new IllegalArgumentException("item not found");
head = head.next;
if(head == null)
tail = null;
}
public void extractLast() {
if(tail == null)
throw new IllegalArgumentException("item not found");
if (head == tail)
head = tail = null;
else {
Element previous = head;
while (previous.next != tail)
previous = previous.next;
previous.next = null;
tail = previous;
}
}
Complexity is O(1)
Complexity is O(n)
Singly Linked Lists
65
Deletion – Deleting First and Last Element
66. public void extract(Object obj) {
Element element = head;
Element previous = null;
while(element != null && ! element.data.equals(obj)) {
previous = element;
element = element.next;
}
if(element == null)
throw new IllegalArgumentException("item not found");
if(element == head)
head = element.next;
else
previous.next = element.next;
if(element == tail)
tail = previous;
}
To delete a specific element, we use either the extract method of MyLinkedList
or that of the Element inner class.
Complexity is O(n)
Singly Linked Lists
66
Deletion – Deleting a specific element
67. 67
Doubly Linked Lists Analysis
- Complexity Analysis -
Note: some ideas in this section are repeated in another way, or another
representation way
Both are doing the same operation
67
68. public void append(Object obj){
Element element = new Element(obj, null, tail);
if(head == null)
head = tail = element;
else {
tail.next = element;
tail = element;
}
}
Complexity is O(1)
Doubly Linked Lists
Insertion at the End (append)
68
68
69. Insertion at the Beginning (prepend)
public void prepend(Object obj){
Element element = new Element(obj, head, null);
if(head == null)
head = tail = element;
else {
head.previous = element;
head = element;
}
}
Complexity is O(1)
Doubly Linked Lists
69
69
70. Inserting before the current node (this) that is neither the first nor the last
node:
Complexity is O(1)
Element element = new Element(obj, this, this.previous);
this.previous.next = element;
this.previous = element;
Doubly Linked Lists
70
Insertion Before an Element
70
71. For DoublyLinked list, traversal can be done in either direction: forward, starting from
head, or backward starting from tail.
Example: Count the number of nodes in a linked list.
Element e = head;
while (e != null) {
//do something
e = e.next;
}
Element e = tail;
while (e != null) {
//do something
e = e.previous;
}
public int countNodes(){
int count = 0;
Element e = head;
while(e != null){
count++;
e = e.next;
}
return count;
}
Complexity is O(n)
Doubly Linked Lists
71
Traversal
71
72. public int sumLastNnodes(int n){
if(n <= 0)
throw new IllegalArgumentException("Wrong: " + n);
if(head == null)
throw new ListEmptyException();
int count = 0, sum = 0;
Element e = tail;
while(e != null && count < n){
sum += ((Integer)e.data).intValue();
count++;
e = e.previous;
}
if(count < n)
throw new IllegalArgumentException(“No. of nodes < "+n);
return sum;
}
Example: The following computes the sum of the last n nodes:
Complexity is O(n)
Doubly Linked Lists
72
Traversal (cont…)
72
73. To delete an element, we use either the extract method of DoublyLinkedList or that
of the Element inner class.
public void extract(Object obj){
Element element = head;
while((element != null) && (!element.data.equals(obj)))
element = element.next;
if(element == null)
throw new IllegalArgumentException("item not found");
if(element == head) {
head = element.next;
if(element.next != null)
element.next.previous = null;
}else{
element.previous.next = element.next;
if(element.next != null)
element.next.previous = element.previous;
}
if(element == tail)
tail = element.previous;
}
Complexity is O(n)
Doubly Linked Lists
73
Deletion
73
74. Summary
An array is a sequenced collection of elements, normally of the same data type.
An alternative to array-based implementations are linked structures.
A linked structure uses object references to create links between objects.
A linked list dynamically grows as needed and essentially has no capacity limitations.
The order in which references are changed is crucial to maintaining a linked list.
Linked list can be Singly-Linked or Doubly-Linked.
Each node in a singly linked list stores element and link to the next node.
Each node in a doubly linked list stores element, link to the previous node and link to the
next node.
In circular linked lists, the last node points to the first node of the list.
Java has a LinkedList class defined as part of the Java collection framework.
So you simply declare an instance of the LinkedList class and call member methods as
required.
74
74
75. References
Java Software Structures - Designing and Using Data Structures, 4th edition, Lewis and Chase.
Data Structures and Problem Solving Using Java, 4th edition, Weiss.
Data Structures & Algorithms in Java, 3rd edition, Drozdek.
Data Structures and Algorithm Analysis in Java, 3rd edition, Weiss.
Algorithms, 4th edition, Sedgewick and Wayne.
A Practical Introduction to Data Structures and Algorithm Analysis, 3rd edition, Shaffer.
Data Structures and Algorithms in Java, 6th edition, Goodrich, Tamassia and Goldwasser.
Foundations of Computer Science, 2nd Edition, Forouzan and Ferous.
www.asyrani.com
http://faculty.kfupm.edu.sa/ICS/jauhar/ics202/
75
75