Linked List
Linked List
Linked List
Objective:
• To understand linked list as a linear, dynamic data
structure
• Compare and contrast arrays and linked lists
• To understand the mechanism through which the
nodes in linked list are accessed
• Describe operations defined for a linked list
• To understand applications of linked lists
Introduction
• Array is a static data structure -> cannot be
extended or reduced to fit the data set during
execution
• Expensive to implement new insertions and
deletions
• Linked Lists addresses some of the limitations of
arrays
• A linked list is a linear data structure where each
element is a separate object.
Introduction
• A linked list is a linear data structure which can
change (grow or shrink in size) during execution
(dynamic)
– Two successive elements are connected by link (self
referential structure)
struct node
– Last element points to NULL
{
– It does not waste memory space. int data;
struct node *next;
}
Points:
• To keep track of a linked list:
– Pointer to the first element of the list (called start, head, etc.) is
essential header linked list
• Head is not a separate node, but the reference to the first node
– If the list is empty then the head is a null reference
• Linear relationship Each element except the first has a unique
predecessor, and each element except the last has a unique
successor
• Every node typically consists of two fields
– data (the information contained in the node)
– next (pointer to the next node)
Operations on a singly linked list
• Insert
– At the beginning of the list
– In the end of the list
– In the middle of the list
• Delete
– From the beginning of the list
– From the end of the list
– From the middle of the list
• Traverse
Writing Methods
• When trying to code methods for Linked Lists draw
pictures!
– If you don't draw pictures of what you are trying to do it
is very easy to make mistakes!
Insertion at the beginning of the list
This is to be done:
Following loop will find previous to the last node after termination
tmp = head
while(tmp->next != NULL)
prev = tmp
tmp = tmp->next
Algorithm to delete from the end
Data_Type DELETE_END_LL(head)
.head = tmp
.while(tmp->next != NULL)
. prev = tmp
. tmp = tmp->next
.prev->next = NULL
.val = tmp->data
.free(tmp)
.return(val)
•Time complexity – O(n); n – number of nodes
Deletion of a node from the middle of the list
List in hand:
Steps:
1. Move to the node to be deleted (with a specific value, 65 in the
current example), keeping track of previous pointer:
head 5 12 8 3 -3 1 2 0
Addition of two polynomials using LLs
(5x2 + 4x + 2) + (5x + 5) = ?
Steps:
1. Start with the highest power of each polynomial (LLs)
2. In case no item having same exponent found, simply append the
term to the resultant list, and continue with the process
3. Wherever exponents are matched, add the corresponding
coefficients and store the term in the resultant list
4. If one list gets exhausted earlier and other list still contains some
lower order terms, append the remaining terms to the resultant list
Array versus Linked Lists
• Arrays are suitable for:
– Inserting/deleting an element at the end.
– Randomly accessing any element.
– Searching the list for a particular value.
• Linked lists are suitable for:
– Inserting an element.
– Deleting an element.
– Applications where sequential access is required.
– In situations where the number of elements cannot be
predicted beforehand.
Types of Lists
• Depending on the way in which the links are used to
maintain adjacency, several different types of linked
lists are possible.
– Linear singly-linked list (or simply linear list)
• One we have discussed so far.
head
A B C
Circular linked list
• The pointer from the last element in the list points back to
the first element.
• There is no node pointing to NULL
• Advantage
– Useful in implementation of circular queue
– Entire list can be traversed from any node of the list
• Disadvantage:
– Reversing of circular list is a complex task
– May end up in an infinite loop if proper care is not taken
Doubly linked list (DLL)
• Pointers exist between adjacent nodes in both directions
(next & prev)
• Usually two pointers are used to keep track of the list, head
and tail
• Advantage:
– The list can be traversed either forward or backward =>
operations such as delete a node and reverse LL becomes easy
• Disadvantage:
– Every node of DLL require extra space for a ‘prev’ pointer; incurs
maintenance overhead
All the operations performed on SLL can be performed on DLL as well
Insert at the beginning of a DLL
INSERT_BEGINING_DLL(head, val)
1. Create a new node NewNode
2. NewNode->prev = NULL
3. NewNode->data = val
4. NewNode->next = head
5. head->prev = NewNode
6. head = NewNode
# Time complexity is O(1)
Insert a node into existing DLL @ position pos
Figure: 1
Figure: 2
Figure: 3
Figure: 4
Figure: 5
INSERT_END_DLL(head, val)
1. Create a new node NewNode Worst case
2. NewNode->prev = NULL time
3. NewNode->data = val complexity of
4. NewNode->next = NULL the algorithm
5. tmp = head is O(n),
considering
6. while(tmp->next != NULL)
‘n’ nodes are
7. tmp = tmp->next there
8. tmp->next = NewNode
9. NewNode->prev = tmp
Delete from the beginning
Type DEL_BEGINNING_DLL(head)
//Delete from beginning
1. tmp = head
2. val = tmp->data
3. head = tmp->next
. free(tmp)
. Return val
– linear: for every node in the list, there is one and only one node
that precedes it (except for possibly the first node, which may have
no predecessor,) and there is one and only one node that succeeds
it, (except for possibly the last node, which may have no successor)
if(start->next != NULL )
fun(start->next->next);
printf("%d ", start->data);
}
(A) 1 4 6 6 4 1
(B) 1 3 5 1 3 5
(C) 1 2 3 5
(D) 1 3 5 5 3 1
Discussion:
void fun(struct node* start)
{
1. if(start == NULL)
2. return;
3. printf("%d ", start->data);
4. if(start->next != NULL )
5. fun(start->next->next);
6. printf("%d ", start->data);
}
• fun() prints alternate nodes of the given LL
– first from head to end, statements 3, 4, 5 till 1 is satisfied
– then from end to head, 1 satisfied, stmt. 5 runs till beginning
– If Linked List has even number of nodes, skips the last node
• For 1->2->3->4->5->6; 1, 3, 5 and 5, 3, 1 will be printed (D)
Q. In the worst case, the number of comparisons
needed to search a singly linked list of length n for a
given element is (GATE CS 2002)
(A) log2 n
(B) n/2
(C) (log2 n – 1)
(D) n
Answer: (D)
Q. Suppose each set is represented as a linked list
with elements in arbitrary order. Which of the
operations among union, intersection, membership,
cardinality will be the slowest?
A. union only
B. intersection, membership
C. membership, cardinality
D. union, intersection
Discussion:
• Membership and Cardinality require a single scan to
a LL; resulting in linear time complexity - O(n)
• Assume two LLs, LL1 (cardinality n1) and LL2
(cardinality n2). For union of LL1 and LL2, one need
to ensure no duplicate elements is present – needs
O(n1×n2) operations for each element we need to
check if that element exists in other set
• Same argument is applicable for intersection