Why not just use Arrays?
Arrays are fast for access, but they are rigid:
- Fixed Size: You must reallocate and copy the entire array to grow it.
- Expensive Insertions: Inserting at the beginning requires shifting every other element.
A Linked List is a sequence of Nodes scattered throughout the heap. Each node knows only two things: its data and where the next node is.
Self-Referential Structures
To build a node, we need a structure that contains a pointer to itself. This is called a self-referential structure.
struct Node {
int data; // The payload
struct Node *next; // Pointer to the next node
};
The Head Pointer
The “Head” is just a standard pointer that stores the address of the first node. If the list is empty, head is NULL.
Traversing the List
To move through the list, we use a temporary pointer. We never move the head pointer itself during traversal, or we will lose the list!
struct Node *current = head;
while (current != NULL) {
printf("%d -> ", current->data);
current = current->next;
}
Insertion at the Head
Inserting at the head is an operation regardless of the list size.
- Create a new node.
- Set
new_node->nextto the currenthead. - Update
headto point to thenew_node.
Interactive Lab
Memory Cleanup
// To delete a list, we must free every node. struct Node *tmp; while (head != NULL) { tmp = head; head = ; free(tmp); }
The Price of Dynamicity
Linked lists are powerful but come with costs:
- No Random Access: To get the 100th element, you must visit the previous 99.
- Cache Inefficiency: Because nodes are scattered in memory, they suffer from frequent cache misses.
- Memory Overhead: Each node uses extra bytes for the
nextpointer.
Runtime Environment
Interactive Lab
1#include <stdio.h>
2#include <stdlib.h>
3
4struct Node {
5 int data;
6 struct Node *next;
7};
8
9int main() {
10 // Creating a simple 2-node list: [10] -> [20] -> NULL
11 struct Node *head = malloc(sizeof(struct Node));
12 head->data = 10;
13 head->next = malloc(sizeof(struct Node));
14 head->next->data = 20;
15 head->next->next = NULL;
16
17 struct Node *curr = head;
18 while(curr) {
19 printf("%d ", curr->data);
20 curr = curr->next;
21 }
22
23 // Proper cleanup omitted for brevity
24 return 0;
25}
System Console
Waiting for signal...