3
3
LINKED LISTS
Linked list
Linked list is a linear data structure used to store similar data in memory. The
elements in linked list are not stored in contiguous memory locations but are stored
randomly.
Linked list is a collection of elements known nodes which contain two fields of
information. One contains the data item and the other contains the link or address of the
Successor list element. A node can be represented as,
Representation of a linked list in memory
Let LIST is linear linked list. It needs two linear arrays for memory
representation. Let these linear arrays are INFO and LINK. INFO[K] contains the
information part and LINK[K] contains the next pointer field of node K. A variable START
is used to store the location of the beginning of the LIST and NULL is used as next pointer
sentinel which indicates the end of LIST. It is shown below:
EXAMPLE:
Singly Linked List:
Singly linked lists are one of the most primitive data structures. Each
node that makes up a singly linked list consists of a value, and a reference to
the next node (if any) in the list.
Operations on a
single linked
list:
Insertion
In general when people talk about insertion with respect to linked lists
of any form they implicitly refer to the adding of a node to the tail of the list.
When you use an API like that of DSA and you see a general purpose method
that adds a node to the list, you can assume that you are adding the node to
the tail of the list not the head.
1. head = Ø in which case the node we are adding is now both the head
and tail of the list; or
2. We simply need to append our node onto the end of the list updating
the tail reference appropriately.
Algorithm:
1) algorithm Add(value)
2) Pre: value is the value to add to the list
3) Post: value has been placed at the tail of the list
4) nnode(value)
5) if head = Ø
6) head n
7) tail n
8) else
9) tail.Next n
10) tail n
11) end if
12) end Add
Searching
Deleting a node from a linked list is straightforward but there are a few
cases we need to account for:
1. The list is empty; or
2. The node to remove is the only node in the linked list; or
3. We are removing the head node; or
4. We are removing the tail node; or
5. The node to remove is somewhere in between the head and tail; or
6. The item to remove doesn't exist in the linked list.
The algorithm whose cases we have described will remove a node from
any-where within a list irrespective of whether the node is the head etc. If
you know that items will only ever be removed from the head or tail of the
list then you can create much more concise algorithms. In the case of always
removing from the front of the linked list deletion becomes an O(1)
operation.
Algorithm:
Advantages and
disadvantage of
single linked list:
Advantage:-
Disadvantage:-
3 4 - 3 3 - 8 2 - 10 1 NULL
Doubly Linked List
A doubly linked list is a list that contains links to next and previous
nodes. Unlike singly linked lists where traversal is only one way, doubly
linked lists allow traversals in both ways. A generic doubly linked list node
can be designed as:
struct node {
int data;
struct node* prev;
struct node* next;
};
Node:
Example:
Insertion
Insertion of a node in a linked list can be done at three
places, viz. at start, in between at a specified location or at end.
Update the next pointer of the new node to the head node and
make prevpointer of the new node as NULL
Now update head node’s prev pointer to point to new node and
make new node as head node.
Traverse the list to end. Let’s call the current last node of list as
Last node.
Make next pointer of New node to point to NULL and prev pointer
of new node to point to Last node.
Update next pointer of Last node to point to new Node.
if(*head == NULL)
{
printf("\nList Empty.");
position=1;
}
if(!newNode)
{
printf("\nError while allocating memory to new Node");
return;
}
newNode->data = value;
if(position==1)
{
printf("\nInserting node at the beginning of the list");
newNode->next = *head;
newNode->prev = NULL;
//*head->prev = newNode;
*head = newNode;
return;
}
temp = *head;
while((currentNodePosition<position-1)&& (temp->next!=NULL))
{
temp = temp->next;
currentNodePosition++;
}
if(temp->next==NULL)
{
printf("\nInserting node at the last.");
newNode->next = temp->next;
newNode->prev = temp;
temp->next = newNode;
}
else
{
printf("\nInserting node at position : %d",position);
newNode->next = temp->next;
newNode->prev = temp;
temp->next->prev = newNode;
temp->next = newNode;
return;
}
}
Deletion
As similar to Insertion of a node in a linked list, deletion can also be
done at three places, viz. from start, in between at a specified location or
from end.
Traverse the list till end. While traversing maintain the previous
node address also. Thus when we reach at end then we have one
pointer pointing to NULL and other pointing to penultimate node.
Update the next pointer of penultimate node to point to NULL.
Dispose off the Last Node.
if(*head == NULL)
{
printf("\nList is empty");
return;
}
if(position == 1)
{
temp = temp->next;
if(*head != NULL)
{
temp->prev = NULL;
}
free(temp);
return;
}
while((currentNodePosition<position)&& (temp->next!=NULL))
{
printf("\nDeleting node from starting");
temp = temp->next;
currentNodePosition++;
}
if(temp->next == NULL)
{
printf("\nDeleting node from last");
temp2 = temp->prev;
temp2->next = NULL;
free(temp);
return;
}
else
{
temp2 = temp->prev;
temp2->next = temp->next;
temp->next->prev = temp2;
free(temp);
return;
}
}
A circular linked list is a linked list in which last element or node of the
list points to first node. For non-empty circular linked list, there are no NULL
pointers. The memory declarations for representing the circular linked lists
are the same as for linear linked lists. All operations performed on linear
linked lists can be easily extended to circular linked lists with following
exceptions:
While inserting new node at the end of the list, its next pointer
field is made to point to the first node.
While testing for end of list, we compare the next pointer field
with address of the first node
Circular linked list is usually implemented using header linked list.
Header linked list is a linked list which always contains a special node called
the header node, at the beginning of the list. This header node usually
contains vital information about the linked list such as number of nodes in
lists, whether list is sorted or not etc. Circular header lists are frequently
used instead of ordinary linked lists as many
operations are much easier to state and implement using header
list this comes from the following two properties of circular
header linked lists:
The null pointer is not used, and hence all pointers contain valid
addresses
Every (ordinary) node has a predecessor, so the first node may
not require a special case.