Lists & Linked ListsBefore deleting a node in a linked list, we apply the search algorithm. If the...
Transcript of Lists & Linked ListsBefore deleting a node in a linked list, we apply the search algorithm. If the...
1
Lists & Linked Lists
(Section 4)
College of Computer Science and Engineering
Taibah University
S1, 1438
Algorithms and Data Structures(CS211 & CS202)
Lecture Scope
Arrays
Linked Lists
Singly Linked List
Doubly Linked List
Linked Lists Analysis (Complexity Analysis)
With Singly Linked List
With Doubly Linked List
2
2
3
Arrays
4
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
3
5
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…)
6
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…)
4
Declared using [ ] operator
1- datatype[] arrayRefVar;
Example:
double[] myList;
OR
2- datatype arrayRefVar[]; // This style is allowed
Example:
double myList[];
Arrays (Declaration)
7
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
8
Arrays (Storage in Memory)
5
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)
9
Arrays (Terminology)
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
10
Arrays (Terminology) (cont…)
6
Each array element has a subscript (index), used to
access the element.
Subscripts (index) start at 0
11
Arrays (Accessing Array Elements)
0 1 2 3 4Subscripts
(index)
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
12
Arrays (Example)
7
13
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
Multi-Dimensional Arrays (cont…)
Two-Dimensional Array Example:
14
8
15
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
16
The following algorithm gives an example of finding the average of elements
in array whose elements are reals.
Operations on Array (cont…)
9
17
A record is a collection of related elements, possibly of different
types, having a single name.
Each element in a record is called a field.
A field is the smallest element of named data that has meaning.
A field has a type and exists in memory.
Fields can be assigned values, which in turn can be accessed for
selection or manipulation.
A field differs from a variable primarily in that it is part of a record.
Records
18
Two examples of records: The first example, fraction,
has two fields, both of which are integers. The second
example, student, has three fields made up of three
different types.
Records (cont…)
10
19
If we need to define a combination of elements and at the same time
some attributes of each element, we can use an array of records.
For example, in a class of 30 students, we can have an array of 30
records, each record representing a student.
Array of Records
20
Example:
The following shows how we access the fields of
each record in the students array to store values in
them.
Array of Records (cont…)
11
21
However, we normally use a loop to read data into an array of records.
Algorithm 11.2 shows part of the pseudocode for this process.
Array of Records (cont…)
22
Both an array and an array of records represent a
list of items.
An array can be thought of as a special case of an
array of records in which each element is a record
with only a single field.
Arrays versus Array of Records
12
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
23
24
Linked Lists
13
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
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
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
26
14
Linked Structures (cont…)
A Person object, for instance, could contain a reference
to another Person object
A series of Person objects would make up a linked list:
27
Linked Structures (cont…)
Links could also be used to form more complicated,
non-linear structures
28
15
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
29
Allocate elements one at a time as needed, have each element
keep track of the next element
Result is referred to as linked list of elements, track next element
with a pointer
Array of Elements in Memory
Linked List
Jane AnneBob
Jane Anne Bob
Linked Lists (cont…)
30
16
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
The last node points to NULL
A
data pointer
node
Linked Lists (cont…)
31
Linked Lists (cont…)
There are no index values built into linked lists
To access each node in the list you must follow the references
from one node to the next
Person current = first;
while (current != null)
{
System.out.println(current);
current = current.next;
}
32
17
MakeEmpty
InsertNode
DeleteNode
IsEmpty
FindNode
DisplayList
Transformers
Observers
Linked Lists Operations
33
Care must be taken to maintain the integrity of the links
To insert a node at the front of the list, first point the new node to
the front node, then reassign the front reference
34
Linked Lists Operations (cont…)
18
To delete the first node, reassign the front reference accordingly
If the deleted node is needed elsewhere, a reference to it must be
established before reassigning the front pointer
35
Linked Lists Operations (cont…)
Before insertion into a linked list, we first apply the searching algorithm.
If the flag returned from the searching algorithm is false, we will allow
insertion, otherwise we abort the insertion algorithm, because we do
not allow data with duplicate values.
Four cases can arise:
Inserting into an empty list.
Insertion at the beginning of the list.
Insertion at the end of the list.
Insertion in the middle of the list.
Linked Lists Operations (Inserting a Node)
36
19
37
Before deleting a node in a linked list, we apply the search algorithm.
If the flag returned from the search algorithm is true (the node is
found), we can delete the node from the linked list.
Two cases:
Deleting the first node
Deleting any other node.
In other words, the deletion of the last and the middle nodes can be
done by the same process.
Linked Lists Operations (Deleting a node)
38
Retrieving means randomly accessing a node for the purpose of
inspecting or copying the data contained in the node.
Before retrieving, the linked list needs to be searched. If the data
item is found, it is retrieved, otherwise the process is aborted.
Retrieving uses only the cur pointer, which points to the node
found by the search algorithm.
Linked Lists Operations (Retrieving a node)
20
39
To traverse the list, we need a “walking” pointer, which is a pointer
that moves from node to node as each element is processed.
We start traversing by setting the walking pointer to the first node in
the list. Then, using a loop, we continue until all of the data has been
processed.
Each iteration of the loop processes the current node, then
advances the walking pointer to the next node. When the last node
has been processed, the walking pointer becomes null and the loop
terminates.
Linked Lists Operations (Traversing a node)
There are many variations on the basic linked list
concept
Linked list can be Singly-Linked or Doubly-Linked
Variations of Linked Lists
40
21
A doubly linked list contains next and previous members
A single linked list contains only a next member.
41
Variations of Linked Lists (cont…)
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…)
42
22
2 8 3 5Circular singly linked list
2 8 35
list
list
Circular doubly linked list
Variations of Linked Lists (cont…)
Circular linked lists
43
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
44
Singly Linked Lists
23
1. Allocate a new node
2. Insert the new element
3. Have the new node point
to old head
4. Update head to point to
the new node
Inserting at the Head
45
Singly Linked Lists
Algorithm addFirst(v)
{
v.setNext(head); // make v point to the old head node
head = v; // make head point to the new node
size = size + 1; // increment the node count
}
Inserting at the Head (cont…)
46
Singly Linked Lists
24
1. Update head to point
to next node in the list
2. Allow garbage
collector to reclaim the
former first node
Removing at the Head
47
Singly Linked Lists
Algorithm removeFirst()
{
if ( head = null )
Indicate an error: the list is empty;
t = head ;
/* make head point to the next node (or null) */
head = head.getNext();
t.setNext(null); //null out the next pointer of the removed node
size = size - 1; //decrement the node count
}
Removing at the Head (cont…)
48
Singly Linked Lists
25
1. Allocate a new node
2. Insert the new element
3. Have the new node
point to null
4. Have the old last node
point to new node
5. Update tail to point to
new node
Inserting at the Tail
49
Singly Linked Lists
Algorithm addLast(v)
{
v.setNext(null); //make the new node v point to null object
tail.setNext(v); //make the old tail node point to the new node
tail = v ; //make tail point to the new node
size = size +1; //increment the node count
}
Inserting at the Tail (cont…)
50
Singly Linked Lists
26
Removing the tail node of a
singly linked list cannot be
done in constant time.
We need to traverse the
whole linked list to remove
the tail node, which takes
O(n) time, where n is the
number of nodes in the linked
list.
51
Removing at the TailSingly Linked Lists
Algorithm removeLast()
{
if ( size = 0 )
Indicate an error: the list is empty;
else
{
if ( size = 1 ) // only one node
head = null;
else // at least two nodes
{
t = head; /* make t point to the head */
while ( t.getNext != null ) /* find the last node */
{
s = t;
t = t.getNext();
}
s.setNext(null); //null out the next pointer of the last node
}
size = size - 1; //decrement the node count
}
}
52
Removing at the Tail (cont…) Singly Linked Lists
27
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
trailerheader nodes/positions
elements
node
Doubly Linked Lists
53
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
BA C
54
Doubly Linked Lists (cont…)
28
/** 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; }
} 55
The Node Class of Doubly Linked List
(a) Before the insertion
Rome Seattle New York
Rome Seattle New YorkSydney
(b) After the insertion
header trailer
header trailer
56
Doubly Linked Lists
Inserting at the Head
29
Algorithm addFirst(v)
{
w = header.getNext(); // make w point to the first node
v.setNext(w); // make v point to the old first node
v.setPrev(header); // make v point to the header
w.setPrev(v); // make the old first node point to v
header.setNext(v); // make header point to v
size = size+1; // increment the node count
}
57
Doubly Linked Lists
Inserting at the Head (cont…)
(a) Before the insertion
Rome Seattle New York
Seattle Sydney New YorkRome
(b) After the insertion
header trailer
header trailer
58
Doubly Linked Lists
Inserting in the Middle
30
Algorithm addAfter(v,z)
{
w=v.getNext(); // make w point to the node after v
z.setPrev(v); // link z to its predecessor, v
z.setNext(w); // link z to its successor, w
w.setPrev(z); // link w to its new predecessor, z
v.setNext(z); // link v to its new successor, z
size = size+1; // increment the node count
}
59
Doubly Linked Lists
Inserting in the Middle (cont…)
Seattle Sydney New YorkRome
(a) Before the deletion
header trailer
Rome Seattle Sydney
header trailer
(b) After the deletion
60
Doubly Linked Lists
Removing at the Tail
31
Algorithm removeLast():
{
if ( size = 0 )
Indicate an error: this list is empty;
v = trailer.getPrev() // make v point to the last node
u = v.getPrev(); // u points to the node before the last node
trailer.setPrev(u);
u.setNext(trailer);
v.setPrev(null);
v.setNext(null);
size = size -1;
}
61
Doubly Linked Lists
Removing at the Tail (cont…)
Seattle Sydney New YorkRome
(a) Before the deletion
header trailer
(b) After the deletion
Rome Seattle New York
header trailer
62
Doubly Linked Lists
Removing in the Middle
32
Algorithm remove(v):
{
u = v.getPrev() // make u point to the node before v
w = v.getNext(); // w points to the node after v
w.setPrev(u); // link out v
u.setNext(w);
v.setPrev(null); // null out the pointers of v
v.setNext(null);
size = size -1; // decrement the node count
}
63
Doubly Linked Lists
Removing in the Middle (cont…)
64
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
33
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.
Linked List Example Using JAVA
65
import java.util.LinkedList;
LinkedList list = new LinkedList();
list.add(new Integer(10)); //list.add(new object)
// the add() member method requires an object and not
a primitive data type.
Linked List Example Using JAVA (cont…)
66
34
67
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args) throws IOException
{ LinkedList list = new LinkedList();
list.add(new Integer(10));
list.add(new Integer(20));
list.add(new Integer(30));
for(int i=0; i<list.size(); i++)
{
Integer temp = (Integer)list.get(i);
System.out.println(temp);
}
for(int i=list.size()-1; i>=0; i--)
{ Integer temp = (Integer)list.get(i);
System.out.println(temp);
}
}
}
Output
10
20
30
30
20
10
67
Linked List Example Using JAVA (cont…)
68
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
35
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)
69
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)
70
36
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
71
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
72
37
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
73
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
74
Deletion – Deleting First and Last Element
38
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
75
Deletion – Deleting a specific element
76
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
39
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)
77
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
78
40
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
79
Insertion Before an Element
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
80
Traversal
41
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
81
Traversal (cont…)
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
82
Deletion
42
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.83
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.
Slides at: http://faculty.kfupm.edu.sa/ICS/jauhar/ics202/
84
43
Any Question
???
85