0% found this document useful (0 votes)
10 views34 pages

Unit 2 New-1-34

A linked list is a linear data structure that consists of nodes connected by pointers, allowing dynamic memory allocation and efficient insertion and deletion operations. It has advantages over arrays, such as flexibility in size and efficient memory usage, but suffers from slower access times and additional memory overhead for pointers. The document also covers various types of linked lists, including singly, doubly, and circular linked lists, along with their operations and complexities.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views34 pages

Unit 2 New-1-34

A linked list is a linear data structure that consists of nodes connected by pointers, allowing dynamic memory allocation and efficient insertion and deletion operations. It has advantages over arrays, such as flexibility in size and efficient memory usage, but suffers from slower access times and additional memory overhead for pointers. The document also covers various types of linked lists, including singly, doubly, and circular linked lists, along with their operations and complexities.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

Linked List

What is a Linked List?


A linked list is a linear data structure used for storing collections of data.
A linked list has the following properties.
Successive elements are connected by pointers
The last element points to NULL
Can grow or shrink in size during execution of a program
Can be made just as long as required (until systems memory exhausts)
Does not waste memory space (but takes some extra memory for pointers). It allocates memory as list
grows.

Example of Single Linked List

Linked Lists ADT


The following operations make linked lists an ADT:
Main Linked Lists Operations
Insert: inserts an element into the list
Delete: removes and returns the specified
position element from the list

Why Linked Lists?


Both linked lists and arrays are used to store collections of data, and since both are used for the same
purpose, we need to differentiate their usage.
That means in which cases arrays are suitable and in which cases linked lists are suitable.

Arrays Overview
One memory block is allocated for the entire array to hold the elements of the array. The array elements
can be accessed in constant time by using the index of the particular element as the subscript.
Why Constant Time for Accessing Array Elements?
To access an array element, the address of an element is computed as an offset from the base address of
the array and one multiplication is needed to compute what is supposed to be added to the base address to
get the memory address of the element. First the size of an element of that data type is calculated and then
it is multiplied with the index of the element to get the value to be added to the base address.
This process takes one multiplication and one addition. Since these two operations take constant time, we
can say the array access can be performed in constant time.

Advantages of Arrays

• Simple and easy to use


• Faster access to the elements (constant access)

Disadvantage of Array
First Disadvantage of Arrays:
Preallocates all needed memory up front and wastes memory space for indices in the array that are empty.
Fixed size: The size of the array is static (specify the array size before using it).

Second Disadvantage of Arrays


One block allocation: To allocate the array itself at the beginning, sometimes it may not be possible to get
the memory for the complete array (if the array size is big).
Eg: A[10000]

Third Disadvantage of Arrays


Complex position-based insertion: To insert an element at a given position, we may need to shift the existing
elements .This will create a position for us to insert the new element at the desired position. If the position at
which we want to add an element is at the beginning, then the shifting operation is more expensive.
– A[20]

Advantages of Linked Lists


Linked lists have both advantages and disadvantages.
Issues in arrays:
To create an array, we must allocate memory for a certain number of elements.
To add more elements to the array when full, we must create a new array and copy the old array into the new
array. This can take a lot of time. We can prevent this by allocating lots of space initially but then we might
allocate more than we need and waste memory.

Advantages of Linked Lists


The advantage of linked lists is that they can be expanded in constant time.
With a linked list, we can start with space for just one allocated element and add on new elements easily
without the need to do any copying and reallocating.

Issues with Linked Lists (Disadvantages)


There are a number of issues with linked lists.
The main disadvantage of linked lists is access time to individual elements.
Array is random-access, which means it takes O(1) to access any element in the array.
Linked lists take O(n) for access to an element in the list in the worst case.
Another advantage of arrays in access time is spacial locality in memory. Arrays are defined as contiguous
blocks of memory, and so any array element will be physically near its neighbors. This greatly benefits from
modern CPU caching methods

Although the dynamic allocation of storage is a great advantage, the overhead with storing and retrieving data
can make a big difference. Sometimes linked lists are hard to manipulate.
If the last item is deleted, the last but one must then have its pointer changed to hold a NULL reference.
This requires that the list is traversed to find the last but one link, and its pointer set to a NULL reference.
Finally, linked lists waste memory in terms of extra reference points.

Singly Linked Lists


Generally “linked list” means a singly linked list.
This list consists of a number of nodes. Each node has a next pointer to the following element.
The link of the last node in the list is NULL, which indicates the end of the list.

Following is a type declaration for a linked list of integers:


Basic Operations on a List
• Traversing the list
• Inserting an item in the list
• Deleting an item from the list
Traversing the Linked List
Let us assume that the head points to the first node of the list.
To traverse the list we do the following
Follow the pointers.
Display the contents of the nodes (or count) as they are traversed.
Stop when the next pointer points to NULL.

The ListLength() function takes a linked list as input and counts the number of nodes in the list.
The function given below can be used for printing the list data with extra print function.
Time Complexity: O(n), for scanning the list of size n.
Space Complexity: O(1), for creating a temporary variable.

Singly Linked List Insertion


Insertion into a singly-linked list has three cases:
Inserting a new node before the head (at the beginning)
Inserting a new node after the tail (at the end of the list)
Inserting a new node at the middle of the list
(random location)
Note: To insert an element in the linked list at some position p, assume that after inserting the element
the position of this new node is p.

Inserting a Node in Singly Linked List at the Beginning


In this case, a new node is inserted before the current head node. Only one next pointer needs to be
modified (new node’s next pointer) and it can be done in two steps:
– Update the next pointer of new node, to point to the current head.

Inserting a Node in Singly Linked List at the Beginning(Diagram)


Inserting a Node in Singly Linked List at the Ending
In this case, we need to modify two next pointers
Last nodes next pointer and new nodes next pointer.
New node’s next pointer points to NULL.

Inserting a Node in Singly Linked List at the Ending (Diagram)


Inserting a Node in Singly Linked List at the Middle
Let us assume that we are given a position where we want to insert the new node.
In this case also, we need to modify two next pointers.
If we want to add an element at position 3 then we stop at position 2. That means we traverse 2 nodes and insert the
new node.
For simplicity let us assume that the second node is called position node.
The new node points to the next node of the position where we want to add this node

Let us write the code for all three cases. We must update the first element pointer in the calling
function, not just in the called function.
For this reason we need to send a double pointer. The following code inserts a node in the singly linked
list.
Code for Inserting a Node

Note: We can implement the three variations of the insert operation separately.
Time Complexity: O(n), since, in the worst case, we may need to insert the node at the end of the list.
Space Complexity: O(1), for creating one temporary variable.
Singly Linked List Deletion
Similar to insertion, here we also have three cases.
• Deleting the first node
• Deleting the last node
• Deleting an intermediate node.

Deleting the First Node in Singly Linked List


First node (current head node) is removed from the list. It can be done in two steps:
Create a temporary node which will point to the same node as that of head.

Now, move the head nodes pointer to the next node and dispose of the temporary node.

Deleting the Last Node in Singly Linked List


In this case, the last node is removed from the list. This operation is a bit trickier than removing the first
node, because the algorithm should find a node, which is previous to the tail. It can be done in three
steps:
Traverse the list and while traversing maintain the previous node address also. By the time we reach the
end of the list, we will have two pointers, one pointing to the tail node and the other pointing to the node
before the tail node.
Update previous node’s next pointer with NULL.

Dispose of the tail node.

Deleting an Intermediate Node in Singly Linked List


In this case, the node to be removed is always located between two nodes. Head and tail links are not
updated in this case. Such a removal can be done in two steps:
Similar to the previous case, maintain the previous node while traversing the list. Once we find
the node to be deleted, change the previous node’s next pointer to the next pointer of the node to be
deleted.
Dispose of the current node to be deleted.
Time Complexity: O(n). In the worst case, we may need to delete the node at the end of the list.
Space Complexity: O(1), for one temporary variable.

Deleting Singly Linked List


This works by storing the current node in some temporary variable and freeing the current node.
After freeing the current node, go to the next node with a temporary variable and repeat this process for
all nodes.
Time & Space Complexity
Time Complexity: O(n), for scanning the complete list of size n.
Space Complexity: O(1), for creating one temporary variable

Doubly Linked Lists

The advantage of a doubly linked list (also called two – way linked list) is that given a node in the list, we can
navigate in both directions.
A node in a singly linked list cannot be removed unless we have the pointer to its predecessor.
But in a doubly linked list, we can delete a node even if we don’t have the previous node’s address (since each
node has a left pointer pointing to the previous node and can move backward).

Disadvantages
The primary disadvantages of doubly linked lists are:
Each node requires an extra pointer, requiring more space.
The insertion or deletion of a node takes a bit longer (more pointer operations).

Following is a type declaration for a doubly linked list of integers:

Doubly Linked List Insertion


Insertion into a doubly-linked list has three cases (same as singly linked list):
Inserting a new node before the head.
Inserting a new node after the tail (at the end of the list).
Inserting a new node at the middle of the list.

Inserting a Node in Doubly Linked List at the Beginning


In this case, new node is inserted before the head node.
Previous and next pointers need to be modified and it can be done in two steps:
Update the right pointer of the new node to point to the current head node (dotted link in below figure) and
also make left pointer of new node as NULL.

Update head node’s left pointer to point to the new node and make new node as head.

Inserting a Node in Doubly Linked List at the Ending


In this case, traverse the list till the end and insert the new node.
New node right pointer points to NULL
left pointer points to the end of the list.
Update right pointer of last node to point to new node.

Inserting a Node in Doubly Linked List at the Middle


Traverse the list to the position node and insert the new node.
New node right pointer points to the next node of the position node where we want to insert the new node.
New node left pointer points to the position node.

I Step
II Step
Position node right pointer points to the new node
The next node of position node left pointer points to new node.

Now, let us write the code for all of these three cases.
Update the first element pointer in the calling function, not just in the called function.
For this reason we need to send a double pointer.
The following code inserts a node in the doubly linked list

Code
Doubly Linked List Deletion
Similar to singly linked list deletion, here we have three cases:
• Deleting the first node
• Deleting the last node
• Deleting an intermediate node

Deleting the First Node in Doubly Linked List


In this case, the first node (current head node) is removed from the list. It can be done in two steps:
Create a temporary node which will point to the same node as that of head.
Now, move the head nodes pointer to the next node and change the heads left pointer to NULL. Then,
dispose of the temporary node.

Deleting the Last Node in Doubly Linked List


This operation is a bit trickier than removing the first node, because the algorithm should find a node,
which is previous to the tail first. This can be done in three steps:
Traverse the list and while traversing maintain the previous node address also. By the time we reach the
end of the list, we will have two pointers, one pointing to the tail and the other pointing to the node
before the tail.

Update the next pointer of previous node to the tail node with NULL.
Dispose the tail node.
Deleting an Intermediate Node in Doubly Linked List
In this case, the node to be removed is always located between two nodes, and the head and tail links are
not updated. The removal can be done in two steps:
Similar to the previous case, maintain the previous node while also traversing the list. Upon
locating the node to be deleted, change the previous node’s next pointer to the next node of the node to
be deleted.

Dispose of the current node to be deleted.


Time Complexity: O(n), for scanning the complete list of size n.
Space Complexity: O(1), for creating one temporary variable.
Circular Linked Lists

In singly linked lists and doubly linked lists, the end of lists are indicated with NULL value.
Circular linked lists do not have ends.
In circular linked lists, each node has a successor.
In singly linked lists, there is no node with NULL pointer in a circularly linked list.

Usage of circular linked lists


When several processes are using the same computer resource (CPU) for the same amount of time, we
have to assure that no process accesses the resource before all other processes do (round robin
algorithm).

Declaration of node
The following is a type declaration for a circular linked list of integers:

In a circular linked list, we access the elements using the head node (similar to head node in singly linked
list and doubly linked lists).
The circular list is accessible through the node marked head.
To count the nodes, the list has to be traversed from the node marked head, with the help of a dummy
node current, and stop the counting when current reaches the starting node head.
If the list is empty, head will be NULL, and in that case set count = 0.
Otherwise, set the current pointer to the first node, and keep on counting till the current pointer
reaches the starting node.

Time Complexity: O(n), for scanning the complete list of size n.


Space Complexity: O(1), for creating one temporary variable.

Printing the Contents of a Circular Linked List


We assume here that the list is being accessed by its head node. Since all the nodes are arranged in a
circular fashion, the tail node of the list will be the node previous to the head node.
Let us assume we want to print the contents of the nodes starting with the head node. Print its contents,
move to the next node and continue printing till we reach the head node again.
Time Complexity: O(n), for scanning the complete list of size n.
Space Complexity: O(1), for temporary variable.

Inserting a Node at the End of a Circular Linked List


Let us add a node containing data, at the end of a list (circular list) headed by head.
The new node will be placed just after the tail node (which is the last node of the list), which means it will
have to be inserted in between the tail node and the first node.
Create a new node and initially keep its next pointer pointing to itself.

Update the next pointer of the new node with the head node and also traverse the list to the tail. That
means in a circular list we should stop at the node whose next node is head.
Update the next pointer of the previous node to point to the new node and we get the list as shown below.

Inserting a Node at the Front of a Circular Linked List


The only difference between inserting a node at the beginning and at the end is that, after inserting the new
node, we just need to update the pointer. The steps for doing this are given below:
Create a new node and initially keep its next pointer pointing to itself.

Update the next pointer of the new node with the head node and also traverse the list until the tail. That
means in a circular list we should stop at the node which is its previous node in the list.
Update the previous head node in the list to point to the new node.

Make the new node as the head.


Time Complexity: O(n), for scanning the complete list of size n.
Space Complexity: O(1), for temporary variable.

Deleting the Last Node in a Circular Linked List


The list has to be traversed to reach the last but one node. This has to be named as the tail node, and its
next field has to point to the first node. Consider the following list.
To delete the last node 40, the list has to be traversed till you reach 7. The next field of 7 has to be
changed to point to 60, and this node must be renamed pTail
Traverse the list and find the tail node and its previous node.

Update the next pointer of tail node’s previous node to point to head.
Dispose of the tail node.

Time Complexity: O(n), for scanning the complete list of size n.


Space Complexity: O(1), for a temporary variable.
Deleting the First Node in a Circular List
The first node can be deleted by simply replacing the next field of the tail node with the next field of the first
node.

Find the tail node of the linked list by traversing the list. Tail node is the previous node to the head node which
we want to delete.

Create a temporary node which will point to the head. Also, update the tail nodes next pointer to point to next
node of head (as shown below).
Now, move the head pointer to next node. Create a temporary node which will point to head. Also, update the
tail nodes next pointer to point to next node of head (as shown below).

Time Complexity and Applications


Time Complexity: O(n), for scanning the complete list of size n.
Space Complexity: O(1), for a temporary variable.
Applications of Circular List
Circular linked lists are used in managing the computing resources of a computer. We can use circular lists for
implementing stacks and queues.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy