Module 12 – part 1 – Linked Lists
BITS Pilani
Pilani Campus
Department of Computer Science & Information Systems
Module Overview
• Motivation
• Linked Lists Implementation
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
BITS Pilani
Pilani Campus
Motivation
Random Access List vs
Sequential Access List
Random Access List:
• Given a list of elements, you should be able to access any element
of the list:
• quickly
• easily
• without traversing any other element of the list
• Example: Using arrays to represent the list.
int arr[100] = {5,8,34,98,13,25,73,88,28,30};
5 8 34 98 13 25 73 88 28 30
• You can access 3rd element of the array by arr[2]
• This is quick, easy and doesn’t need one to traverse the entire
list to read the 3rd element
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Random Access List vs
Sequential Access List
Sequential Access List
• There is another way of representing lists where you should traverse
the list to reach any element of the list.
head
ele next ele next ele next ele next NULL
1st element 2nd element 3rd element 4th element
Accessing 3rd element
• To access 3rd element of the list you need to traverse 1st, 2nd elements
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Linked Lists
In other words, to access the value of 3rd element of
head
the list, you need to traverse the following nodes:
Head → 1st node → 2nd node → 3rd node
ele next ele next ele next ele next NULL
1st node 2nd node 3rd node 4th node
Accessing value stored at 3rd node
• Lists are now organized as a sequence of nodes, each containing a
• value of the element stored at that node: ele
All the nodes
• address of the next node: next together
• The head node contains the address of the first node represent a list
• The last node points to NULL, meaning end of the list or a sequence
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Linked List in Memory
• The nodes are not
sequentially arranged
in the memory
node1 ele next
• They are logically
connected with links
Illustrating a linked list of
head node3 ele next NULL
three nodes in the memory
node2 ele next
ele next ele next ele next
NULL
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Sequential Access Lists - Uses
Where are Sequential Access Lists useful?
• Create dynamic lists on run-time
• you can keep on adding nodes to the list, without bothering
about resizing the list, like in arrays when the number of
elements exceed their size
• Efficient insertion and deletion
• Without any shift operations
• Used to implement
• Stacks
• Queues
• Other user-defined data types
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
BITS Pilani
Pilani Campus
Linked lists Implementation
Linked Lists
head
ele next ele next ele next ele next NULL
1st node 2nd node 3rd node 4th node
To create linked lists we need two kinds of structures:
• One for storing the head
• The other to represent each node in the list
Let us see how each of these can be defined…
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Self referential structures
Before we see the structure definition of linked lists, let us see
what self-referential structures are:
“Self-referential structures contain a pointer member that
points to a structure of the same structure type”
Self-referential
structures
Wrong Declaration essentially store
Correct Declaration
a pointer
struct self_ref struct self_ref variable to of its
{ { own type to
reference to
int data; int data;
another structure
struct self_ref b; struct self_ref *b; variable of its
}; }; kind.
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Linked Lists
count head stores the address of the first node
count stores the number of nodes/elements in the list
head
ele in each node stores the element (integer in this case)
next stores the address of the next node in the list
ele next ele next ele next ele next NULL
1st node 2nd node 3rd node 4th node
Consider that our linked list stores integer elements.
struct node{ struct linked_list{
int ele; int count;
struct node * next; struct node * head;
}; };
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Creating linked list using
malloc() (on heap segment)
typedef struct node * NODE; typedef struct linked_list * LIST;
struct node{ struct linked_list{
int ele; int count;
NODE next; NODE head;
}; };
LIST createNewList(){
LIST myList;
myList = (LIST) malloc(sizeof(struct linked_list));
// myList = (LIST) malloc(sizeof(*myList));
myList->count=0;
myList->head=NULL; myList count=0
return myList;
head=NULL
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Creating new node
typedef struct node * NODE; typedef struct linked_list * LIST;
struct node{ struct linked_list{
int ele; int count;
NODE next; NODE head;
}; };
NODE createNewNode(int value){
NODE myNode;
myNode = (NODE) malloc(sizeof(struct node));
// myList = (NODE) malloc(sizeof(*myNode));
myNode->ele=value;
myNode->next=NULL; myNode ele=value
return myNode;
} next=NULL
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
main()
int main(){
LIST newList = createNewList();
NODE n1 = createNewNode(10);
NODE n2 = createNewNode(20);
NODE n3 = createNewNode(30);
insertNodeAtBeginning(n1,newList);
insertNodeAtBeginning(n2,newList);
insertNodeAtEnd(n3,newList);
NODE n4 = createNewNode(40);
insertAfter(10,n4,newList);
removeFirstNode(newList);
removeLastNode(newList);
return 0;
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Inserting a node at the
beginning of the list
void insertNodeAtBeginning(NODE n1, LIST l1){
// case when list is empty
if(l1->count == 0) { count=0 10
l1->head = n1; head NULL next NULL
n1->next = NULL;
l1->count++;
}
// case when list is non empty
else {
... ... count=1
} head
10
}
next NULL
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Inserting a node at the beginning of the list
(contd.)
void insertNodeAtBeginning(NODE n1, LIST l1){
// case when list is empty
if(l1->count == 0) {
... ...
} Insertion is usually done at
// case when list is non empty the beginning of the list.
else { It is very fast. Doesn’t
n1->next = l1->head; require any traversal or
l1->head = n1; shifting of elements
l1->count++;
} n1 10
}
next NULL
count=3 4 10 30 25
l1 head
next next next NULL
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Inserting a node at the end of
the list
void insertNodeAtEnd(NODE n1, LIST l1){
// case when list is empty
This case is same as insert at
if(l1->count == 0) {
the beginning of an empty
l1->head = n1; list.
n1->next = NULL;
l1->count++;
}
// case when list is non empty
else {
... ...
}
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Inserting a node at the end of
the list
void insertNodeAtEnd(NODE n1, LIST l1){
... ...
// case when list is non empty • Traverse the list until the end.
else { • Insert new node at the end
NODE temp = l1->head;
while(temp->next!=NULL)
{
temp = temp->next;
}
temp->next = n1;
n1->next = NULL;
l1->count++; n1 10
} next NULL
}
count=3 4 10 30 25
l1 head
next next next NULL
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Inserting a node after a given
node
void insertAfter(int searchEle, NODE n1, LIST l1){ else{
// case when list is empty if(temp->next == NULL) {
… … temp->next = n1;
// case when list is non-empty n1->next = NULL;
else { l1->count++;
NODE temp = l1->head; }
NODE prev = temp; else {
while(temp!=NULL) { prev = temp;
if (temp->ele == searchEle) temp = temp->next;
break; prev->next = n1;
prev = temp; n1->next = temp;
temp = temp->next; l1->count++;
} }
if(temp==NULL) { return;
printf("Element not found\n"); }
return; }
} return;
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Removing a node from the
beginning of the list
void removeFirstNode(LIST l1)
{
if (l1->count == 0)
{
printf("List is empty. Nothing to remove\n");
}
else
{
NODE temp = l1->head;
l1->head = temp->next;
temp
free(temp);
l1->count--;
10
}
return; next
}
count=3 2 30 25
head
l1 next next NULL
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Removing a node from the end
of the list
void removeLastNode(LIST l1) else
{ {
if (l1->count == 0) NODE temp = l1->head;
{ NODE prev = temp;
while((temp->next) != NULL)
printf("List is empty\n");
{
}
prev=temp;
else if(l1->count == 1)
temp = temp->next;
{ }
l1->count--; prev->next = NULL;
free(l1->head); l1->count--;
l1->head = NULL; free(temp);
} }
return;}
count=3 2 10 30 25
l1 head
next next NULL next NULL
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Other functions
Exercise: Implement the following functions for a linked list:
• search(int data, LIST mylist): returns the node that contains its
ele=data
• printList(LIST mylist): prints the elements present in the entire list in
a sequential fashion
• removeElement(int data, LIST mylist): removes the node that
has its ele=data
• isEmpty(LIST mylist): checks if the list is empty or not
• Modify the insert/delete functions to first check whether the list is empty using
isEmpty() function.
In each of the above, you must have to decide which one is an appropriate
datatype for the same.
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
BITS Pilani
Pilani Campus