Linked List
Linked List
Module 4
         Linked List
     Other list structures
           Hashing
Syllabus
   Module 1   Data Structure operations
              Sorting algorithms
              Dynamic memory allocation
   Module 2   Stacks
              Representation of Stacks in C
              Applications
   Module 3   Queues
   Module 4   Linked List
              Other list structures
              Hashing
Other list structures - Circular lists and it’s primitive operations, Doubly linked
lists and it’s primitive operations, Applications of linked lists: Addition of long
positive integers, addition of Polynomials.
Special name is given to the address of first node as Head and last
node in the linked list can be identified because its next portion
points to Null
Linked list Data Structure
• A node contains two fields i.e. data stored at that particular
  address and the pointer which contains the address of the next
  node in the memory.
• The last node of the list contains pointer to the null.
Uses of Linked List
✓The list is not required to be contiguously present in the memory.
 The node can reside any where in the memory and linked together
 to make a list. This achieves optimized utilization of space.
✓list size is limited to the memory size and doesn't need to be
 declared in advance.
✓Empty node can not be present in the linked list.
✓We can store values of primitive types or objects in the singly
 linked list.
Why use linked list over array?
Array contains following limitations:
1.The size of array must be known in advance before using it in the program.
2.Increasing size of the array is a time taking process. It is almost impossible
 to expand the size of the array at run time.
3.All the elements in the array need to be contiguously stored in the memory.
 Inserting any element in the array needs shifting of all its predecessors.
Linked list is the data structure which can overcome all the limitations
of an array. Using linked list is useful because,
1.It allocates the memory dynamically. All the nodes of linked list are non-
 contiguously stored in the memory and linked together with the help of
 pointers.
2.Sizing is no longer a problem since we do not need to define its size at the
 time of declaration. List grows as per the program's demand and limited to
 the available memory space.
Singly Linked List
Arrange the name of the students
according to the 1st letter of their names
Michael
               Rock
John
                         Smith
Tony
           Alpha
Mark
23               54                78               90
1000             2000              3000             4000
1000
Head
Self Referential Structure: It is a structure which contains
a pointer to a structure of the same type.
struct abc {
     int a;
     char b;
     struct abc *self;
 };
We use self referential structure for creating a node of the
single linked list
Node representation in C
struct node {
                           Node
    int data;
    struct node *link;
 };
Creating a node in C
#include<stdio.h>
#include<stdlib.h>
struct node {
      int data;
      struct node *link;
                                     Node
 };
void main()                               Null
{
struct node *head = Null;                  head
                                                    1000
head=(struct node *)malloc(sizeof(struct node ));
head->data = 45;                                    head
head->link=Null;
                               45         Null
printf(“%d”, head->data);      1000
}                              1000
                                head
Traversal                             if(head==0)
#include <stdio.h>                    {
#include <stdlib.h>                   head=temp=newnode;
struct node {                         }
   int data;                          else
                                      {
   struct node* next;
                                      temp->next=newnode;
};
                                        temp=newnode;
struct node *head, *newnode, *temp;
                                      }
head=0;
                                      printf(“Do you want to continue (0, 1)\n”);
int choice;                           scanf(“%d”, & choice);
while(choice)                         }              TraversingCode
{                                                    temp=head;
newnode = (struct node*)malloc(sizeof(struct node)); while(temp!=0)
printf(“Enter the data\n”);                          {
scanf(“%d”, &newnode->data);                         printf("%d", temp->data);
newnode->next=0;                                     temp=temp->next;
                                                     }
     Operations on Singly Linked List
     • Insertion
     The insertion into a singly linked list can be performed at different positions.
     Based on the position of the new node being inserted, the insertion is categorized
     into the following categories.
Sl. No    Operation          Description
1.        Insertion at       It involves inserting any element at the front of the list. We just
          beginning          need to a few link adjustments to make the new node as the
                             head of the list.
2.        Insertion at end   It involves insertion at the last of the linked list. The new node
          of the list        can be inserted as the only node in the list or it can be inserted
                             as the last one.
3.        Insertion after    It involves insertion after the specified node of the linked list. We
          specified node     need to skip the desired number of nodes in order to reach the
                             node after which the new node will be inserted
                                 head
                                             500
Insertion at                      100
printf("\nEnter value\n");
scanf("%d",&newnode->data);
newnode->next = head;
head = newnode;
printf("\nNode inserted");
 }
                                          head
                                                        500
Insertion at end                             100
printf("\nEnter value\n");
scanf("%d",&newnode->data);
newnode->next = 0
temp=head;
while(temp->next!=0)
{
temp=temp->next;
}
temp->next=newnode;
                                                          newnode
Insertion at specified location             100                400       5         400
                                                                                         400
int pos, i=1;
struct node {                                       7    200         1       400           9       0
     int data;
     struct node *next;                                100               200                     300
                                               100
};
struct         node     *head,                temp
                                                                                    3      pos
*newnode, *temp;
newnode                       =
(struct node *) malloc(sizeof(                                                     21      i
struct node));
printf("\nEnter             the
position");
scanf("%d",&pos);
if(pos>count)
{
printf(“Invalid position”);
   }                         printf("Enter the data");
else                         scanf("%d", &newdata->data);
{                            newnode->next=temp->next;
temp=head;                   temp->next=newnode;
while(i<pos)
{
Deletion
The Deletion of a node from a singly linked list can be performed at
different positions. Based on the position of the node being deleted,
the operation is categorized into the following categories.
void display()
{                                                                                    8     200
                                          void peek()
struct node *temp;                                                                300
                                          {
temp=top;
                                          if(top==0)                              5   100
if(top==0)
                                          {
{                                                                                 200
                                          printf("stack is empty\n");
printf("stack is empty\n");
                                          }                                       2 0
}
                                          else                                    100
else
                                          {
{
                                          printf("Top element us %d", top->data);
while(temp!=0)
                                          }
{
                                          }
printf("%d", temp->data);
temp=temp->link;
}}}
Implementation of stack using linked list
                                                         head
   top
                                                         200
  300
                                                                7    400   8         100   1    0    2 0
         8         200     5         100   2         0              200            400         100   200
             300               200             100
void pop()
{                                                                              8     200
struct node *temp;
                                                                               300
temp=top;
if(top==0)                                                                     5     100
{
                                                                               200
printf("No elements");
}                                                                              2     0
else                                                                           100
{
printf("%d", top->data);
top=top->link;
free(temp)
}
}
Implementation of Queue using Linked List
                              Front       rear
                              100         100 200 300
  struct node
                                      5          0 200   0     300   -3    0
  {
     int data;                              100          200         300
                                                                               void main()
     struct node *next;               if(front==0&&rear==0)                    {
  };                                  { front=rear=newnode;
                                      }                                        enqueue(5);
  struct node *front=0;
                                      else                                     enqueue(0);
                                      {
  struct node *rear=0;                rear->next=newnode;
                                                                               enqueue(-3);
  void enqueue(int x)                 rear=newnode; } }                        display();
  {                                                                            dequeue();
      struct node *newnode;                                                    peek();
      newnode=(struct node *) malloc(sizeof(struct node));
      newnode->data=x;
                                                                               }
      newnode->next=0;
  }
Implementation of Queue using Linked List
                              Front       rear
                              100         100 200 300
  struct node {
                                      5          0 200   0     300   -3    0
     int data;
     struct node *next;                     100          200         300
                                                                               void main()
  };                                  else                                     {
                                      {
  struct node *front=0;               temp=front;                              enqueue(5);
  struct node *rear=0;
                                      while(temp!=0) {                         enqueue(0);
                                      printf(“%d”, temp->data);
  void display() {                    temp=temp->next;
                                                                               enqueue(-3);
  struct node *temp;                  }                                        display();
  if(front==0 && rear ==0)                                                     dequeue();
  {                                                                            peek();
  printf(“Queue is empty);
  }
                                                                               }
Implementation of Queue using Linked List
                              Front       rear
struct node
{                             The prev part of the first node and
   struct node *prev;         the next part of the last node will
                              always contain null indicating end in
   int data;                  each direction.
    struct node *next;
}
Doubly Linked List
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, we can easily manipulate the elements of the list since the
list maintains pointers in both the directions (forward and
backward).
• In the following 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.
• We can traverse the list in this
  way until we find any node
  containing null or -1 in its next
  part.
Operations on doubly linked list
• Node Creation
struct node
{
   struct node *prev;
   int data;
   struct node *next;
};
struct node *head;
     Operations
Sl. No   Operations                  Descriptions
1        Insertion at beginning     Adding the node into the linked list at beginning.
2        Insertion at end           Adding the node into the linked list to the end.
3        Insertion    at   specified Adding the node into the linked list at the specified node.
         node
4        Deletion at beginning      Removing the node from beginning of the list
5        Deletion at the end        Removing the node from end of the list.
6        Deletion of the node Removing the node which is present just after the node
         having given data    containing the given data.
7        Searching                  Comparing each node data with the item to be searched and
                                    return the location of the item in the list if the item found
                                    else return null.
8        Traversing                 Visiting each node of the list at least once in order to
                                    perform some specific operation like searching, sorting,
                                    display, etc.
Insertion Operation
               head
                            100
struct node{
int data;                           0     5      200         100   4      250        200    2       0
struct node *prev;                                                                         250
                               head       100                    200
struct node *next;                            tail
};                               0 100       0 100 200                                           250
struct node *head, *tail;                                                                        tail
                                           0       5      0 200      0 100 6     0
void createdll(){
struct node *newnode;                              100                   200
while(choice) {
newnode=(struct node*)malloc(size of(struct node) if(head==0){
head=0;                                              head=tail=newnode;
printf(“Enter the data”);                            }
scanf(“%d”, &newnode->data);                         else{
newnode->prev=0;                                     tail->next=newnode;
                                                     newnode->prev=tail;
newnode->next=0;
                                                      tail=newnode;
                                                      printf(“Do you want to continue(1,0)”);
                                                      scanf(“%d”, &choice);
Insertion Operation:
               head
                     Insert at the beginning
                         150 500
struct node{
int data;                          0 500       5   100        150     4   200   100    1       0
struct node *prev;                                                                    200
                                           150                      100
struct node *next;
};                                                                                          200
                                   0       6       0 150      500
struct node *head, *tail;                                                                   tail
                                                             newnode
void insertatbeg(){                    500
struct node *newnode;
newnode=(struct
node*)malloc(size of(struct                              head->prev=newnode;
node);                                                   newnode->next=head;
head=0;                                                  head=newnode;
printf(“Enter the data”);                                }
scanf(“%d”, &newnode->data);
newnode->prev=0;
newnode->next=0;
Insertion Operation:
               head
                     Insert at the end
                                                                                      tail
                          500
                                                                                          200
struct node{
int data;                           500      5 100        150     4   200    100      1         0 400
struct node *prev;                                                                  200
                                           150                  100
struct node *next;
};
                                    0     6    150
struct node *head, *tail;                                                   0 200         7     0
void insertatend(){                      500
                                                                              400
struct node *newnode;
newnode=(struct node*)malloc(size of(struct node);                                        400
head=0;                                              tail->next=newnode;                  newnode
printf(“Enter the data”);                            newnode->prev=tail;
scanf(“%d”, &newnode->data);                         tail=newnode;
newnode->prev=0;                                     }
newnode->next=0;
Insertion Operation:
               head
                     Insert
                      temp
                            at the pos
                                                                                           tail
                            150        150 100
                                                                                           200
                                                                       500       500
struct node{
int data;                             500    5    100    150     4   200         100   1      0
struct node *prev;                                                                  200
                                            150                100
struct node *next;
                                                                     0 100   7   0 200
};
struct node *head, *tail;         struct node *newnode, *temp;              500   newnode
void insertatpos() {              temp=head;
int pos, i=1;                     newnode=(struct node*)malloc(size of(struct node);
printf(“Enter the position”);     head=0;
scanf(“%d”, &pos);                printf(“Enter the data”);
if(pos<=0 && pos>count){          scanf(“%d”, &newnode->data);
printf(“Invalid position”);       newnode->prev=0;
                                                               newnode->prev=temp;
}                                 newnode->next=0;
                                                               newnode->next=temp->next;
else if(pos==1){                  while(i<pos-1) {
                                                               temp->next=newnode;
insertatbeg();                    temp=temp->next;
                                                               newnode->next->prev=newnode;
}                                 i++;
                                                               }
else{                             }
                                                                             deletefromBeg()
Deletion Operation:
               head
                    Delete
                    temp
                           from Beg                                          deletefromEnd()
                                                                             deletefromPos()
                           200 400       200
struct node {
int data;
struct node *next;
};
struct node *head;
void display()
{
struct node *temp;
if(head==0) {
printf(“List is empty”);
}
else
{
temp=head;
while(temp->next!=head){
printf(“%d”, temp->data);
temp=temp->next;
}
printf(“%d”, temp->data);
}}
                                 head      tail
struct node
                                 200       200 100       Create using head and tail
{
int data;
struct node *next;                   7    100      1     200
};                                     200         100
struct node *head, *tail;
void createCLL(){
int choice=1;
struct node *newnode;
                                                         else
head=0;                                                  {
while(choice){                                           tail->next=newnode;
newnode=(struct node *)malloc(sizeof(struct node));      tail=newnode;
printf(“Enter the data\n”);                              }
scanf(“%d”, &newnode->data);                             tail->next=head;
newnode->next=0;                                         printf(“Enter your choice\n”);
if(head==0)                                              scanf(“%d”, &choice);
                                                         }
{
                                                         printf(“%d”, tail->next->data);
head=tail=newnode;
                                                         }
  }
Creation                                   tail
                                          100 500
struct node {                                               150
int data;
                                     7    100      6     0 100       1   0 100
struct node *next;
                                       100         500                    150
};
struct node *tail;
void createCLL(){
int choice=1;
struct node *newnode;                                    else {
tail=0;                                                  newnode->next=tail->next;
while(choice){                                           tail->next=newnode;
newnode=(struct node *)malloc(sizeof(struct node));      tail=newnode;
                                                         }
printf(“Enter the data\n”);
                                                         printf(“Enter your choice\n”);
scanf(“%d”, &newnode->data);
                                                         scanf(“%d”, &choice);
newnode->next=0;                                         }
if(tail==0)                                              printf(“%d”, tail->next->data);
{                                                        }
tail=newnode;
tail->next=newnode; }
struct node {                temp                            tail
                                           500                                           200
 struct node{
 int data;
                                       5     600     4    100   1      200           7          500
 struct node *next;
 };                                    500               600        100                   200
 struct node *tail;
 void deletefromBeg(){
 struct node *temp;
 temp=tail->next;                                               temp                     tail
 if(tail==0)                                                     600               600
 {
                            tail->next=temp->next;
 printf(“List is empty”);
                            free(temp);                                5     600
 }
 else{                                                                     600
 if(tail==temp)
 {
 tail=0;
 free(temp);
 }
 else{
Deletion from Circular Linked List:
Deletion from End          temp
                                                                                          tail
                                            500                                           200
 struct node{
 int data;
                                        5      600    4    100   1      200           7          500
 struct node *next;
 };                                      500              600        100                   200
 struct node *tail;
 void deletefromEnd(){
 struct node *temp, *prev;
 temp=tail->next;                                                temp                     tail
 if(tail==0)                                                      600               600
 {
                             while(temp->next!=tail->next){
 printf(“List is empty”);
                             prev=temp;                                 5     600
 }
                             temp=temp->next;
 else if(tail==temp)                                                        600
                             }
 {
                             prev->next=tail->next;
 tail=0;
                             tail=prev;
 free(temp);
                             free(temp);
 }
                             }
 else{
Deletion from Circular Linked List:
Deletion from Pos          temp                                            prev
                                                                                                tail
                    67 mod 10 = 7             Storing
                                       Retrieving / Searching
                                                                        5
                                                                        6
                                                                 67     7
                                                                 48     8
                                                                        9
    Collision in Hashing
0
1    91
2    52   Suppose if we want to add 62 then how to store 62?
3    83   This process is called collision
4    24
           0
5                             Collision Resolution Techniques
           1   91
6
           2   52    62
7    67
8    48
           3   83          Chaining                      Open addressing
           4   24          (Open hashing)                (Closed hashing)
9                                                        • Linear Probing
           5                                             • Quadratic Probing
           6                                             • Double Probing
           7   67
           8   48
           9
Chaining (Open hashing)                    0       10
                                           1
                                           2       42
Keys: 42, 19, 10, 12                       3
Hash Function: k mod 5                     4       19
Advantages: Deletion is easy
             Insertion is easy O(1)
                                               0        10
                                               1
Disadvantages: Searching is O(n)               2        12   42
                Extra space                    3
Load factor = Total number of elements/slots   4        19
            = 4/5
Linear Probing                                              0   19
                                                            1
                                                            2   72
• Keys: 43, 135, 72, 23, 99, 19, 82                         3   43
• Hash Function h(k): k mod 10                              4   23
20                                                                       6    70
                                                   70                    7
20 mod 11 = 9                                      70 mod 11=4
                                                    h2(k)=8-(70 mod 8)   8
                                                          =8-6           9    20
34                                                        =2
                   h2(k)=8-(45 mod 8)                                    10
34 mod 11=1               =8-5
                                                   4+1(2) mod 11
                                                   4+2 mod 11
                          =3                       6 mod 11
45                 h1(k)+i h2(k)mod 11             6
                   1+ 1(3) mod 11
45 mod 11=1         1+3 mod 11
                     4 mod 11= 4