0% found this document useful (0 votes)
11 views20 pages

DSA Assignment - 5

Uploaded by

secretscorpio99
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)
11 views20 pages

DSA Assignment - 5

Uploaded by

secretscorpio99
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/ 20

UNIK KHANAL

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:

1. Insertion at kth Position:

● Traverse the list to the (k-1)th node.


● Create a new node.
● Adjust the pointers to insert the new node.

2. Deletion at kth Position:

● Traverse the list to the kth node.


● Adjust pointers of neighboring nodes to skip the kth node.
● Delete the kth node.

Example:

#include <stdio.h>
#include <stdlib.h>

struct Node {
int data;
struct Node* prev;
struct Node* next;
};

struct Node* createNode(int data) {


UNIK KHANAL

struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));


newNode->data = data;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}

void insertAtK(struct Node** head, int k, int data) {


struct Node* newNode = createNode(data);
if (k == 1) {
newNode->next = *head;
if (*head != NULL)
(*head)->prev = newNode;
*head = newNode;
return;
}

struct Node* current = *head;


int i;
for (i = 0; i < k - 2 && current != NULL; i++)
current = current->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;
}

void deleteAtK(struct Node** head, int k) {


if (*head == NULL) {
printf("List is empty. Nothing to delete.\n");
return;
}

struct Node* temp = *head;


if (k == 1) {
*head = temp->next;
if (*head != NULL)
(*head)->prev = NULL;
free(temp);
return;
}

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);
}

void display(struct Node* head) {


while (head != NULL) {
printf("%d ", head->data);
head = head->next;
}
printf("\n");
}

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.

The process of implementing a stack using linked list are as follows:

● 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.

The process of implementing a queue using linked list are as follows:

● 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.

Merits of contiguous list are:

● 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.

Demerits of contiguous list are:

● 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

Merits of Linked List:

● 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.

Demerits of Linked List:

● 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

5. Differentiate between Singly linked list, DLL, CLL and DCLL.

The Differences Between SLL, DLL, CLL & DCLL are as follows:

Feature SLL DLL CLL DCLL


Direction of Forward & Forward &
Forward Forward
Traversal Backward Backward
Memory
Low High Low High
Overhead
Traversal Forward Both Forward Both Forward
Forward Only
Efficiency Only & Backward & Backward
More More
Insertion / Efficient at Efficient at
Efficient due Efficient due
Deletion Start & End Start & End
to Backward to Backward
Last Node Last Node
Circular
No No Points to Points to
Reference
First Node First Node
UNIK KHANAL

6. Explain why linked list is called dynamic list?

Linked lists are considered dynamic list because of following reasons, they are:

● Dynamic Memory Allocation: In a linked list, memory for nodes is allocated


dynamically as needed. Unlike arrays, which have a fixed size determined at
compile time, linked lists can grow or shrink based on the number of elements being
added or removed. This dynamic allocation of memory allows linked lists to adapt to
changing data requirements during program execution.

● 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

7. Write the algorithm for deleting a new node before a node.

To delete a node before given node singly linked list -

Case 1: check if list is empty


Show message that list is empty.
Case 2: If list has only one element
Show message that no node available before that node to delete.
Case 3: If to delete a node before second node
Step 1: Delete first node
Step 2: Make second node as first node
Step 3: Free the memory occupied by first node
Case 4: If to delete any other node..
Step 1: Traverse the list to reach that node before which a node to delete
Step 2: Maintain the two node which contain the address of previous
node (preAddress) and previous to previous node(tempAddress).
Step 3: Assign the address of node before which node to delete to the
address field of previous-to-previous node.
Step 4: Free the memory occupied by node.
UNIK KHANAL

8. How do you insert a node at last in a doubly linked list? Explain

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

9. What do you mean by a double linked list? Explain with examples.

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

Representation of doubly linked list

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?

The benefits of using linked lists over array are:

● 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.

● Efficient Insertions and Deletions: Insertions and deletions at arbitrary positions in


a linked list can be done with constant time complexity (O(1)), provided the
position is known. In contrast, insertions and deletions in arrays may require
shifting elements, resulting in a time complexity of O(n), where n is the number of
elements.

● 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.

● No Pre-allocation: Linked lists do not require pre-allocation of memory. Memory is


allocated dynamically as needed, reducing the risk of running out of memory or
wasting memory on unused elements.

● Easy to Implement Certain Operations: Certain operations, such as splitting a list


or merging two lists, are easier to implement with linked lists compared to arrays.
Linked lists allow for more efficient splitting and merging without the need for
extensive copying of elements.
UNIK KHANAL

● 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.

● Ease of Concatenation: Concatenating two linked lists can be done simply by


adjusting pointers, while concatenating two arrays typically requires creating a new
array and copying elements.

● 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

11. How can you insert a node in a singly linked list.

We can insert a node in a singly linked list by following ways:

● 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

12. Explain array implementation of lists.

Here's an overview of the array implementation of lists:

● 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.

○ Accessing: Elements in the array can be accessed directly using their


indices, allowing for random access to elements.

○ 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

● Efficiency Considerations: The efficiency of list operations in the array


implementation depends on factors such as the size of the list, the location of
insertions and deletions, and the resizing strategy (if applicable). Insertions and
deletions at the beginning or middle of the list may require shifting a large number
of elements, resulting in higher time complexity compared to linked list
implementations.

● Space Efficiency: The array implementation may be less space-efficient compared


to linked list implementations, especially if the array size is fixed and larger than
the actual number of elements in the list. In such cases, there may be wasted space
in the array.

You might also like