DSA Assignment - 5
DSA Assignment - 5
1. How do you insert and delete a node at kth position of the doubly linked list ?
To insert and delete a node at the kth position of a doubly linked list, you need to traverse
the list to the desired position. Here are the steps for both operations:
Example:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* prev;
struct Node* next;
};
if (current == NULL) {
printf("Index out of range\n");
return;
}
newNode->next = current->next;
if (current->next != NULL)
current->next->prev = newNode;
UNIK KHANAL
current->next = newNode;
newNode->prev = current;
}
int i;
for (i = 0; temp != NULL && i < k - 1; i++)
temp = temp->next;
if (temp == NULL) {
printf("Index out of range\n");
return;
}
if (temp->next != NULL)
temp->next->prev = temp->prev;
UNIK KHANAL
if (temp->prev != NULL)
temp->prev->next = temp->next;
free(temp);
}
int main() {
struct Node* head = NULL;
// Example usage
insertAtK(&head, 1, 10);
insertAtK(&head, 2, 20);
insertAtK(&head, 3, 30);
insertAtK(&head, 4, 40);
display(head); // Output: 10 20 30 40
deleteAtK(&head, 3);
display(head); // Output: 10 20 40
return 0;
}
UNIK KHANAL
2. Describe the process of implementing stack and queue using a linked list.
● Node Structure: Define a structure for a node in the linked list. Each node will
contain a data field and a pointer to the next node.
● Stack Structure: Define a structure to represent the stack. This structure will
typically contain a pointer to the top of the stack.
● Push Operation: To push an element onto the stack, allocate a new node, set its
data field to the element to be pushed, and set its next pointer to the current top of
the stack. Then update the top pointer to point to the newly created node.
● Pop Operation: To pop an element from the stack, check if the stack is empty. If
not, update the top pointer to point to the next node in the stack and free the
memory of the popped node.
● Peek Operation: To peek at the top element of the stack, simply return the data
field of the top node.
● Node Structure: Define a structure for a node in the linked list. Each node will
contain a data field and a pointer to the next node.
● Queue Structure: Define a structure to represent the queue. This structure will
typically contain pointers to the front and rear of the queue.
UNIK KHANAL
● Enqueue Operation: To enqueue an element into the queue, allocate a new node, set
its data field to the element to be enqueued, and update the next pointer of the
current rear node to point to the new node. Then update the rear pointer to point to
the new node.
● Dequeue Operation: To dequeue an element from the queue, check if the queue is
empty. If not, update the front pointer to point to the next node in the queue and
free the memory of the dequeued node.
● Front Operation: To get the element at the front of the queue, simply return the
data field of the front node.
● Rear Operation: To get the element at the rear of the queue, simply return the data
field of the rear node.
UNIK KHANAL
3. State relative merits and demerits of contiguous list and Linked list.
● It is used to represent multiple data items of same type by using only single name.
● It can be used to implement other data structures like linked lists, stacks, queues,
trees, graphs etc.
● 2D arrays are used to represent matrices.
● Implementation of list using array is easier as compared other implementation.
● The size of the array is fixed. Most often this size is specified at compile time. This
makes the programmers to allocate arrays, which seems “large enough” than
required.
● Inserting new elements at the front is potentially expensive because existing
elements need to be shifted over to make room.
● Deleting an element from an array is not possible. Linked lists have their own
strengths and weaknesses, but they happen to be strong where arrays are weak.
● Generally array’s allocates the memory for all its elements in one block whereas
linked lists use an entirely different strategy. Linked lists allocate memory for each
element separately and only when necessary.
UNIK KHANAL
● Linked lists are dynamic data structures. i.e., they can grow or shrink during the
execution of a program.
● Linked lists have efficient memory utilization. Here, memory is not pre-allocated.
Memory is allocated whenever it is required and it is de-allocated (removed) when
it is no longer needed.
● Many complex applications can be easily carried out with linked lists.
● There is no need to define an initial size for a Linked list.
● Linked List reduces the access time.
● They use more memory than arrays because of the storage used by their pointers.
● Difficulties arise in linked lists when it comes to reverse traversing. For instance,
singly linked lists are cumbersome to navigate backwards and while doubly linked
lists are somewhat easier to read, memory is wasted in allocating space for a
back-pointer.
● Nodes in a linked list must be read in order from the beginning as linked lists are
inherently sequential access.
● Nodes are stored in-contiguously, greatly increasing the time required to access
individual elements within the list, especially with a CPU cache.
UNIK KHANAL
4. Explain the steps involved in inserting and deleting a node in a singly linked list.
Inserting and deleting a node in a singly linked list involves manipulating pointers to
ensure proper connections between nodes. Below are the steps involved in inserting and
deleting a node in a singly linked list:
Inserting a Node:
● Create a new node: Allocate memory for a new node and set its data and next
pointer.
● Locate the insertion point: Traverse the list until reaching the node after which the
new node should be inserted. This could be the end of the list, a specific position,
or based on some condition.
● Adjust pointers: Update the next pointer of the new node to point to the node next
to the insertion point. Update the next pointer of the node preceding the insertion
point to point to the new node.
● Handle edge cases: Consider special cases such as inserting at the beginning of the
list or an empty list.
Deleting a Node:
● Locate the node to be deleted: Traverse the list until reaching the node to be
deleted. Keep track of the previous node to update its next pointer.
● Update pointers: Update the next pointer of the previous node to skip the node to
be deleted and point directly to the node after it.
● Free memory: Deallocate the memory occupied by the node to be deleted.
● Handle edge cases: Consider special cases such as deleting the first node, the last
node, or when the list becomes empty after deletion.
UNIK KHANAL
The Differences Between SLL, DLL, CLL & DCLL are as follows:
Linked lists are considered dynamic list because of following reasons, they are:
● Flexible Size: Linked lists do not have a fixed size limit. They can expand or
contract in size without the need for reallocation or copying of existing elements.
This flexibility makes linked lists suitable for situations where the number of
elements is not known in advance or may change frequently.
● Efficient Insertion and Deletion: Insertion and deletion operations in linked lists are
generally efficient, especially compared to arrays. Adding or removing elements
from a linked list typically involves only adjusting pointers/references, without the
need to shift or resize the entire data structure. This efficiency allows linked lists
to handle dynamic changes in size more effectively.
● Dynamic Structure: Linked lists provide a dynamic data structure where new nodes
can be inserted or removed at any position within the list. Unlike arrays, where
elements are stored contiguously in memory, linked lists allow for arbitrary
insertion and deletion operations, enabling dynamic manipulation of the list's
contents.
UNIK KHANAL
To insert a node at the end of a doubly linked list, you need to follow these steps:
● Create a New Node: Allocate memory for a new node and set its data value.
● Traverse to the Last Node: Start traversing the list from the head node until you
reach the last node. This involves moving the traversal pointer from one node to the
next until you find the node whose next pointer is null.
● Update Pointers: Once you reach the last node, update the next pointer of the last
node to point to the new node, and set the previous pointer of the new node to point
to the last node.
● Update Tail Pointer (if applicable): If your doubly linked list implementation
maintains a tail pointer for efficiency, update the tail pointer to point to the new
node since it is now the last node in the list.
● Handle Special Cases: If the list is empty (head is null), make the new node both
the head and tail of the list. If the list has only one node, update both head and tail
pointers to point to the new node.
UNIK KHANAL
In double linked list, every node has link to its previous node and next node. So, we can
traverse forward by using next field and can traverse backward by using previous field.
Every node in a double linked list contains three fields and they are shown in the following
figure...
Here, 'link1' field is used to store the address of the previous node in the sequence,
'link2' field is used to store the address of the next node in the sequence and 'data'
field is used to store the actual value of that node.
Example:
● In double linked list, the first node must be always pointed by head.
● Always the previous field of the first node must be NULL.
● Always the next field of the last node must be NULL
UNIK KHANAL
struct node
{
int info;
struct node *prev;
struct node *next;
};
typedef struct node NodeType;
NodeType *head=NULL:
UNIK KHANAL
10. What are the benefits of using linked lists over arrays?
● Dynamic Size: Linked lists can dynamically grow or shrink in size during runtime,
unlike arrays which have a fixed size determined at compile time. This dynamic
resizing capability makes linked lists more flexible for managing varying amounts of
data.
● No Wasted Space: Linked lists allocate memory for each element individually,
minimizing wasted space. In contrast, arrays may have unused space if they are
allocated with a size larger than required.
● Ease of Insertion at the Beginning: Insertions at the beginning of a linked list can
be done in constant time, whereas insertions at the beginning of an array require
shifting all elements, resulting in linear time complexity.
● Efficient Memory Usage: Linked lists can use memory more efficiently than arrays
in situations where the size of the data structure is not known in advance or varies
widely.
UNIK KHANAL
● Create a new node: Allocate memory for a new node and set its data and next
pointer.
● Traverse to the insertion point: Traverse the list starting from the head until
reaching the node after which the new node should be inserted. This may involve
iterating through the list until reaching the end or stopping at a specific position
based on the insertion logic.
● Update pointers to insert the new node: Once the insertion point is found, adjust
the pointers to link the new node into the list. Set the next pointer of the new node
to point to the node following the insertion point. Then, update the next pointer of
the node preceding the insertion point to point to the new node.
● Handle special cases: Consider special cases such as inserting at the beginning of
the list or an empty list.
UNIK KHANAL
● Array Structure: Define an array to hold the elements of the list. The size of the
array may be fixed or dynamic, depending on the requirements.
● List Operations:
○ Insertion: To insert an element into the list, you may need to shift existing
elements to make space for the new element. This typically involves moving
elements to the right from the insertion point to make room for the new
element. After shifting, you insert the new element into the appropriate
position in the array.
○ Deletion: To delete an element from the list, you remove the element from
the array and shift the remaining elements to the left to close the gap
created by the deletion.
○ Traversal: You can traverse the list by iterating over the elements of the
array sequentially.
● Dynamic Resizing (if needed): If the array size is fixed and the list needs to grow
beyond its current capacity, you may need to implement dynamic resizing strategies
such as doubling the array size and copying elements to the new array when the
array becomes full.
UNIK KHANAL