Lecture 5 - Linked List
Lecture 5 - Linked List
DATA
STRUCTURES
INTRODUCTION
• Array: a linear collection of data elements in which the elements are stored in
consecutive memory locations.
• While declaring arrays, we have to specify the size of the array, which will restrict
the number of elements that the array can store.
– For example, if we declare an array as int marks[10], then the array can store a
maximum of 10 data elements but not more than that.
– But what if we are not sure of the number of elements in advance?
Since in a linked list, every node contains a pointer to another node which is of the same
type, it is also called a self-referential data type.
A head pointer is
used to track the
first element in the
linked list
Each node is allocated in the heap using malloc(), so the node memory
continues to exist until it is explicitly de-allocated using free().
MEMORY ALLOCATION PROCESS
• C programming language manages memory statically, automatically, or
dynamically.
Free Memory
Heap
Permanent
C Program Instructions Storage Area
Std Std
2 n
header
Std
3 Std
Value of header=? 1
Value of header=2E450
list_
Disadvantages
• The memory is wasted as pointers require extra memory for storage.
• No element can be accessed randomly; it has to access each node sequentially.
• Reverse Traversing is difficult in linked list.
DECLARATION
• create a node of the linked list using a self-referential structure
• declare a head pointer that always points to the first node of the list.
struct node* head;
DYNAMIC MEMORY ALLOCATION
• For example, the statement
newPtr = malloc( sizeof( struct node ) );
• Memory Leak: Not returning dynamically allocated memory when it’s no longer
needed can cause system to run out of memory prematurely.
– Use free to return the memory to system.
TYPES OF LINKED LIST
– Singly Linked List
Insert Delete
Traverse Search
S I N G LY L I N K E D L I S T
INSERTION: IN SINGLY LINKED LIST AT BEGINNING
// Allocate the space for the new node malloc() is used to
struct node *ptr = (struct node *) malloc(sizeof(struct node *)); dynamically allocate a
// store data into the data part of the node single block of
memory in the heap,
ptr → data = data;
and and returns a
//make the link part of the newnode pointing to the existing first node of the list.
pointer to the new
ptr->next = head; block. It is available in
//make the new node as the first node of the list the header file
head = ptr; stdlib.h.
sizeof() is used to
determine size in
bytes of an element
in C. Here it is used
to determine size of
each node and sent
as a parameter to
malloc.
INSERTION: IN SINGLY LINKED LIST AT THE END
There are two scenarios
Scenario 1: (The list is Empty) head == NULL
• .
// allocate the space for the created node
struct node *ptr = (struct node *) malloc(sizeof(struct node *));
//Since, ptr is the only node that will be inserted in the list, we need to make this node
pointed by the head pointer of the list
head = ptr
INSERTION: IN SINGLY LINKED LIST AT THE END
Scenario 2: The list contains at least one node Head != NULL
// temporary pointer temp in order to traverse through the list.
// temp is made to point the first node of the list
temp = head
//traverse through the entire linked list to find the last node
//At the end of the loop, the temp will be pointing to the last node of the list.
while (temp→ next != NULL)
temp = temp → next;
//Assume we allocate the space for the new node (ptr) before, put the data in the related
field and set the next pointer to NULL.
//make the next part of the temp node (which is currently the last node of the list) point
to ptr
temp->next = ptr;
ptr->next = NULL;
INSERTION: IN SINGLY LINKED LIST AT THE END
temp = head
temp->next = ptr;
ptr->next = NULL;
INSERTION: IN SINGLY LINKED LIST AFTER
SPECIFIED NODE temp=head;
• Allocate the space for the new node and add the item to the data part of it.
ptr = (struct node *) malloc (sizeof(struct node));
ptr->data = item;
INSERTION: IN SINGLY LINKED LIST AFTER
SPECIFIED NODE
W: current->next = new
X: current= current->next
Y: new->next = current->next
Z: current = new A: X X X Y W
B: X X X X W Y
C: X X X W Y
D: X X X W Z Y
E: None of the above
SMALLISH QUESTION - 2
Consider the following linked list and
possible commands.Which correctly
orders the list?
A: c = c -‐> next
B: d = d -‐> next
C: c -‐> next = e
D: d -‐> next = c A: A A B E B B B F G:
B: A B B C E B F
E: e -‐> next = d
C: A C B B E B F
F: d -‐> next = NULL D: A B B C D G
G: e --‐> next = NULL E: none of the above
DELETION: IN SINGLY LINKED LIST AT BEGINNING
Senerio I: There is only one node in the list head → next = NULL
ptr = head;
head = NULL;
free(ptr);
DELETION: IN SINGLY LINKED LIST AT THE END
Senerio 2: There are more than
one node in the list and the last
node of the list will be deleted
head → next != NULL
// traverse the node in order to reach the last node of the list
//ptr1 will point to the second last node of the list
while(ptr->next != NULL) {
ptr1 = ptr;
ptr = ptr ->next;
}
ptr1->next = NULL;
free(ptr);
DELETION: IN SINGLY LINKED LIST AFTER THE
SPECIFIED NODE
• We need to keep track of the two nodes. The one which is to be deleted the other one
if the node which is present before that node. For this purpose, two pointers are used:
ptr and ptr1.
ptr=head;
for(i=0;i<loc;i++) {
ptr1 = ptr;
ptr = ptr->next;
if(ptr == NULL) {
printf("\nThere are less than %d elements in the list..",loc);
return;
}
}
DELETION: IN SINGLY LINKED LIST AFTER THE
SPECIFIED NODE
TRAVERSING IN
SINGLY LINKED LIST
• Traversing means visiting each node of the
list once in order to perform some
operation on that
• Traversing a list involves the following steps:
– Assign the address of start pointer to a temp
(here is ptr) pointer.
– Display the information from the data field of
each node
ptr = head;
while (ptr!=NULL)
{
ptr = ptr -> next;
}
SEARCHING IN
SINGLY LINKED LIST
• Searching any element in the list needs traversing
through the list and make the comparison of every
element of the list with the specified element.
struct node
{
int data;
struct node *prev; // Pointer to previous node in DLL
struct node *next; // Pointer to next node in DLL
}
• In a singly linked list, we could traverse only in one direction, because each
node contains address of the next node and it doesn't have any record of its previous
nodes. However, doubly linked list overcome this limitation of singly linked list.
MEMORY REPRESENTATION OF A DOUBLY
LINKED LIST
• In the image, the first element of the list
that is i.e. 13 stored at address 1. The head
pointer points to the starting address 1.
Since this is the first element being added
to the list therefore the prev of the
list contains null. The next node of the list
resides at address 4 therefore the first node
contains 4 in its next pointer.
ptr->data=item;
ptr->next = NULL;
ptr->prev=NULL;
head=ptr;
(ptr)
INSERTION: IN DOUBLY LINKED LIST AT BEGINNING
temp = head;
/* 4. If the Linked List is empty, then make the new node as head */
if (*head_ref == NULL) {
new_node->prev = NULL;
*head_ref = new_node;
return;
}
/* 5. Else traverse till the last node */
while (last->next != NULL)
last = last->next;
INSERTION: IN DOUBLY LINKED LIST AFTER
SPECIFIED NODE
• In order to insert a node after the specified node in the list, we need to skip the required
number of nodes in order to reach the mentioned node and then make the pointer
adjustments as required.
– Allocate the memory for the new node ptr = (struct node *)malloc(sizeof(struct node));
• Otherwise, just traverse the list to reach the last node of the list.
ptr = head;
if(ptr->next != NULL) {
ptr = ptr -> next;
}
DELETION: IN DOUBLY LINKED LIST AT END
(ptr)
DELETION: IN DOUBLY LINKED LIST AFTER THE
SPECIFIED NODE
• Copy the head pointer into a temporary pointer temp. temp = head
• Traverse the list until we find the desired data value. while(temp -> data != val)
temp = temp -> next;
• Check if the node which is to be deleted, is the last node of the list, if it so then we have to
make the next pointer of this node point to null so that it can be the new last node of the list.
• Otherwise, make the pointer ptr point to the node which is to be deleted. Make the next of
temp point to the next of ptr. Make the previous of next node of ptr point to temp. free the ptr.
ptr = temp -> next;
temp -> next = ptr -> next;
ptr -> next -> prev = temp;
free(ptr);