CPCS204: Data Structure 1
Dr. Sahar Shabanah Lecture 4: Singly Linked Lists (3.2)
Object References
An object reference is a variable that stores the address of an object
A reference also can be called a pointer
References often are depicted graphically:
student
John Smith 40725
3.58
References as Links
Object references can be used to create links between objects
Suppose a Student class contains a reference to another Student object
John Smith 40725
3.57
Jane Jones 58821
3.72
References can be used to create a variety of linked structures, such as a linked list:
studentList
Other Dynamic Representations
It may be convenient to implement as list as a doubly linked list, with next and previous
referenceslist
It may be convenient to use a separate header node, with a count and references to both the front and rear of the list
count: 4 front
rear
list
Intermediate Nodes
The objects being stored should not be concerned with the details of the data structure in which they may be stored
For example, the Student class should not
have to store a link to the next Student object in the list
Instead, we can use a separate node class with two parts: 1) a reference to an
independent object and 2) a link to the next node in the list
The internal representation becomes a linked list of nodes
6
Singly Linked List
A singly linked list is a concrete data structure
consisting of a sequence of nodes, forming a linear ordering
Each element of the list contains a pointer to its successor;
The last element contains a null pointer.
A pointer to the first element of the list (called head) is used to keep track of the list.
A B C D
Hea d
7
Singly Linked List
The basic singly linked list is inefficient when adding elements to the end of the list (the
tail ), need to locate the last element by traversing the entire list to find its tail.
To make adding elements to the tail of a list more efficient, keep a second pointer, tail , which points to the last element of the list.
A B C D
Hea d
Tail
Linked Lists 8
Each node stores
Element (data)
link to the next node
Empty Linked List
An empty linked list is defined by:
Head = Tail = Null
List with Single Node
Head = Tail ≠Null
Head Tail
nex t
ele m
nod e
Singly Linked List
Simply Linked List Classes
Two classes are used: Node and List
Declare Node class for the nodes
element: object
next: a link (object reference) to the next node in the list
public class Node {
private Object element;
private Node next; //pointer to node
public Node(){this (null,null);} // Creates a null node public Node(Object e, Node n){ element= e; next= n;}
Public Object getElement(){ return element;}
public Node getNext(){ return next; }
public void setElement(Object newElem){element= newElem;}
public void setNext(Node newNext){ next= newNext; } }
Simply Linked List Classes
Declare List, which contains
head: a pointer to the first node in the list.
Since the list is empty initially, head is set to NULL
Operations on List public class List {
private Node head;
public void List(){ head = NULL;
}//constructor
public bool IsEmpty() { return head == NULL; } public Node InsertNode(int index, double x);
public int FindNode(double x);
public int DeleteNode(double x);
public void DisplayList(void);
}
Simply Linked List Operations
Operations of LinkedList
IsEmpty : determine whether or not the list is empty
InsertNode : insert a new node at a particular position
FindNode : find a node with a given value
DeleteNode : delete a node with a given value
DisplayList : print all the nodes in
the list
Inserting a new node
Four cases of InsertNode:
1. Insert into an empty list:
1. when list is empty (head = NULL),
2. both head and tail must point to the new node.
2. Insert in front (at the head)
3. Insert at back ( at the tail)
4. Insert between two nodes
head tail
13
Inserting at the Head
1.
Have new node point to old head
2.
Update head to point to new node
3.
Increment size of list
head tail
Φ
head tail
Φ
14
Algorithm for Inserting at Head
//Create a new Node new (T);
// store element data T.data = A;
//new node points to old Head node T.next = Head;
If (Head = Null)
then Tail = T //single node-list // Update Head to point to the new node Head = T;
15
Inserting at the Tail
1. Have new node point to null
2. Have old last node point to new node
3. Update tail to point to new node
hea d
tai l
Φ
hea d
tai l
Φ Φ
hea
d tai
l
Φ Tail.next = newNode;
Tail= NewNode;
Linked Lists 16
Algorithm for Inserting at Tail
//Create a new Node new (T);
// store element data T.data = A;
//new node points to Null T.next = Null;
If (Head = Null)
then Head = T//have a single node- list else Tail.next = T;
// Tail to point to new node Tail= T;
17
Inserting between two nodes
1. Have new node point to next of previous node
2. Have old last node point to new node
3. Increment size of list
newNode currNode
head tail
newNode currNode
head tail
newNode.next= currNode.next;
currNode.next=newNode;
18
Removing Node
Four cases occur while removing a node from a linked list:
1. When the list has only one node:
1. dispose the node, pointed by head (or tail)
2. sets both head and tail to NULL.
2. Remove first: first node (current
head node) is removed from the list.
3. Remove last: last node (current tail node) is removed from the list.
4. General case: node to be removed is located between two nodes. Head and tail links are not updated
head tail
19
Removing at the Head
1. Update head to point to
next node in the list
2. Allow garbage
collector to reclaim the former first node
3. Decrement size of list
hea d
tai l
Φ
hea d
tai l
Φ
hea d
tai l
Φ
Linked Lists 20
Algorithm for Removing at the Head
If (Head = Null)
then Output “error” //empty list else{
T = Head;// temporary pointer y = T.data; //save elem data
Head = T.next; //update Head If (Head = Null)
then Tail = Null; //single node Delete(T); //Garbage collection } //End of Algorithm
Notice: Any Removal Algorithm consists of a single statement
21
Removing at the Tail
1. Traverse the list to find the previous
node of the tail
2. Set the tail to point to the previous node
3. Set next of previous node to NULL
hea d
tai l
Φ
hea d
tai l
Φ
temp
hea d
tai l
Φ
temp
hea d
tai l
Φ
temp
hea d
tai l
Φ
temp
Linked Lists 22
Algorithm for Removing at the Tail
Must cycle through the list, starting at the Head, to determine the new Tail-node.
If (Head = Null)
then Output “error” //empty list else {
T = Head; // temporary pointer If (Head=Tail)
then {Head=Null; T=Null}// test for one node else {
while T.next≠Tail do T=T.next;
T.next = Null }
y = Tail.data; //save elem data Delete(Tail); //Garbage collection
Tail = T; //update Tail } //End of Algorithm
23
Removing a node between two nodes
1. Traverse the list to find the previous node for
deleted node
2. Set the previous
node to point to the next of the deleted node
3. Remove
deleted node
hea d
tai l
Φ
hea d
tai l
Φ
temp
hea d
tai l
Φ
temp
hea d
tai l
Φ
temp
hea d
tai l
Φ
temp
Array versus Linked Lists
Linked lists are more complex to code and manage than arrays, but they have some distinct advantages.
Dynamic: a linked list can easily grow and shrink in size.
We don’t need to know how many nodes will be in the list. They are created in memory as needed.
In contrast, the size of the array is fixed at compilation time.
Easy and fast insertions and deletions
To insert or delete an element in an array, we need to copy to temporary variables to make room for new elements or close the gap caused by deleted elements.
With a linked list, no need to move other nodes.
Only need to reset some pointers.