Toen ik jonger was, dacht ik dat het moeilijkste in het leven een carrière kiezen was. Maar niets bleek verder van de waarheidhet navigeren door familieverhoudingen, vooral in een samengesteld gezin, is zoveel complexer.
Dit jaar kwam mijn 15-jarige dochter, Lieke, bij mij en mijn vrouw, Marleen, wonen. Jarenlang woonde Lieke bij haar moeder, Sanne, na onze scheiding. We hadden co-ouderschap, maar Sanne was de primaire verzorger. Onlangs kreeg Sanne echter een baby met haar nieuwe man, en hun kleine huis werd nog krapper. Daarom besloten we dat Lieke tijdelijk bij mij zou wonen, totdat haar moeder en stiefvader een grotere woning hadden gevonden.
Lieke had haar eigen kamer hier, net als Marleens dochters, Femke (17) en Noor (15). Ik wilde dat ze zich thuis voelde, veilig en op haar gemak. Maar in een samengesteld gezin schuurt het altijd, en Lieke was altijd al stil. Ze trok zich terug, las urenlang of tekende in haar schetsboeken, en hoewel ze beleefd was, voelde ze zich meer als een gast dan als deel van het gezin.
Eerst dacht ik dat het gewenning was. Maar een paar weken geleden viel me iets op: Lieke was verd# Linked List
### Singly Linked List
A singly linked list is a linear data structure in which the elements are not stored in contiguous memory locations and each element is connected only to its next element using a pointer.
### **Features of Singly Linked List**
1. **Dynamic Data Structure**: The size of the linked list can grow and shrink at runtime.
2. **Insertion and Deletion**: Insertion and deletion operations are easier compared to Arrays. No need to shift elements after insertion or deletion.
3. **Memory Efficient**: It allocates memory at runtime, so it’s memory efficient.
4. **Implementation**: It can be used to implement other data structures like stacks, queues, graphs, etc.
### **Basic Operations of Singly Linked List**
1. **Insertion**: Adds an element to the linked list.
– **At the beginning**: Insert a node at the start of the linked list.
– **At the end**: Insert a node at the end of the linked list.
– **After a given node**: Insert a node after a given node.
2. **Deletion**: Deletes an element from the linked list.
– **From the beginning**: Delete the first node of the linked list.
– **From the end**: Delete the last node of the linked list.
– **A given node**: Delete a specific node from the linked list.
3. **Search**: Finds a node with a given value in the linked list.
4. **Traversal**: Accesses each element of the linked list.
### **Time Complexity of Singly Linked List Operations**
| Operation | Time Complexity |
|———–|—————–|
| Insertion at the beginning | O(1) |
| Insertion at the end | O(n) |
| Insertion after a given node | O(1) |
| Deletion from the beginning | O(1) |
| Deletion from the end | O(n) |
| Deletion of a given node | O(n) |
| Search | O(n) |
| Traversal | O(n) |
### **Space Complexity of Singly Linked List**
– **Space Complexity**: O(n), where n is the number of nodes in the linked list.
### **Applications of Singly Linked List**
1. **Dynamic Memory Allocation**: Linked lists are used in dynamic memory allocation, where the size of the data structure is not known at compile time.
2. **Implementation of Stacks and Queues**: Linked lists are used to implement stacks and queues.
3. **Graphs**: Linked lists are used to represent graphs (adjacency list representation).
4. **Hash Tables**: Linked lists are used in hash tables to handle collisions.
5. **Undo Functionality**: Linked lists are used in software applications for undo functionality.
### **Advantages of Singly Linked List**
1. **Dynamic Size**: The size of the linked list can be changed at runtime.
2. **Ease of Insertion/Deletion**: Insertion and deletion operations are easier as compared to arrays.
3. **Memory Efficiency**: It allocates memory at runtime, so it’s memory efficient.
### **Disadvantages of Singly Linked List**
1. **Memory Usage**: Extra memory is used to store the pointer to the next node.
2. **Traversal**: Nodes must be accessed sequentially from the first node (head node). Random access is not possible.
3. **Reverse Traversal**: Not efficient for reverse traversal. For reverse traversal, doubly linked list is more efficient.
### **Representation of Singly Linked List**
A singly linked list is represented by a pointer to the first node (head) of the linked list. Each node in a list consists of at least two parts:
1. **Data**: The data part can be of any type (int, float, char, etc.).
2. **Pointer (or reference)**: The pointer to the next node of the same type.
“`c
struct Node {
int data;
struct Node *next;
};
“`
### **Implementation of Singly Linked List in C**
“`c
#include
#include
// Structure for a node
struct Node {
int data;
struct Node *next;
};
// Function to insert a node at the beginning of the linked list
void insertAtBeginning(struct Node **head, int new_data) {
// Allocate memory for new node
struct Node *new_node = (struct Node *)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = *head;
*head = new_node;
}
// Function to insert a node after a given node
void insertAfter(struct Node *prev_node, int new_data) {
if (prev_node == NULL) {
printf(“The given previous node cannot be NULL”);
return;
}
struct Node *new_node = (struct Node *)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = prev_node->next;
prev_node->next = new_node;
}
// Function to insert a node at the end of the linked list
void insertAtEnd(struct Node **head, int new_data) {
struct Node *new_node = (struct Node *)malloc(sizeof(struct Node));
struct Node *last = *head;
new_node->data = new_data;
new_node->next = NULL;
if (*head == NULL) {
*head = new_node;
return;
}
while (last->next != NULL)
last = last->next;
last->next = new_node;
}
// Function to delete a node with a given key
void deleteNode(struct Node **head, int key) {
struct Node *temp = *head, *prev;
if (temp != NULL && temp->data == key) {
*head = temp->next;
free(temp);
return;
}
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) return;
prev->next = temp->next;
free(temp);
}
// Function to print the linked list
void printList(struct Node *node) {
while (node != NULL) {
printf(” %d “, node->data);
node = node->next;
}
}
// Main function
int main() {
struct Node *head = NULL;
insertAtEnd(&head, 1);
insertAtBeginning(&head, 2);
insertAtBeginning(&head, 3);
insertAtEnd(&head, 4);
insertAfter(head->next, 5);
printf(“Linked list: “);
printList(head);
printf(“\nAfter deleting an element: “);
deleteNode(&head, 3);
printList(head);
return 0;
}
“`
### **Output**
“`
Linked list: 3 2 5 6 4
After deleting an element: 2 5 6 4
“`
### **Explanation**
1. **Structure Definition**: The `Node` structure is defined to represent a node in the linked list. It contains an integer `data` and a pointer `next` to the next node.
2. **Insertion at Beginning**: The `insertAtBeginning` function inserts a new node at the beginning of the linked list. It updates the head pointer to point to the new node.
3. **Insertion after a Node**: The `insertAfter` function inserts a new node after a given node. It checks if the given node is `NULL` and then inserts the new node.
4. **Insertion at End**: The `insertAtEnd` function inserts a new node at the end of the linked list. It traverses the list to find the last node and then appends the new node.
5. **Deletion of a Node**: The `deleteNode` function deletes the first occurrence of a node with the given key. It handles the case where the node to be deleted is the head node.
6. **Printing the List**: The `printList` function traverses the linked list and prints the data of each node.
7. **Main Function**: The `main






