Creating a Singly Linked List from Scratch in DSA C++ - Complexity Walkthrough
When we create a singly linked list by adding nodes one by one, it is important to understand how the time needed grows as we add more nodes.
We want to know how the work changes as the list gets longer.
Analyze the time complexity of the following code snippet.
struct Node {
int data;
Node* next;
};
Node* head = nullptr;
void append(int value) {
Node* newNode = new Node{value, nullptr};
if (!head) {
head = newNode;
return;
}
Node* temp = head;
while (temp->next) {
temp = temp->next;
}
temp->next = newNode;
}
This code creates a singly linked list by adding new nodes at the end one by one.
- Primary operation: The while loop that moves through the list to find the last node.
- How many times: For each append, it runs once for each node already in the list, so it grows as the list grows.
Each time we add a new node, we walk through the entire list to find the end.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 1 + 2 + ... + 10 = 55 steps |
| 100 | About 5050 steps |
| 1000 | About 500,500 steps |
Pattern observation: The total work grows roughly like the square of the number of nodes added.
Time Complexity: O(n2)
This means that adding n nodes one by one at the end takes time proportional to n squared, because each new node requires walking through the list so far.
[X] Wrong: "Appending a node always takes the same constant time, so adding n nodes is O(n)."
[OK] Correct: Because each append walks through the existing list to find the end, the time grows with the list length, making total time grow faster than just n.
Understanding how linked list operations scale helps you explain trade-offs clearly and shows you know how to write efficient code in real projects.
"What if we kept a pointer to the last node to avoid walking the list each time? How would the time complexity change?"
Practice
Node in a singly linked list?Solution
Step 1: Understand the Node structure
A node in a singly linked list holds data and a pointer to the next node.Step 2: Identify the pointer direction
Since it is singly linked, the node only points forward to the next node, not backward.Final Answer:
To store data and a reference to the next node -> Option AQuick Check:
Node = data + next pointer [OK]
- Confusing singly linked list with doubly linked list
- Thinking node stores previous node reference
- Assuming node stores list size
Solution
Step 1: Understand pointer syntax in C++
To link nodes, we use a pointer to the next node:Node* next;.Step 2: Check each option
struct Node { int data; Node* next; }; correctly usesNode* next;. Options A, B, and C have invalid syntax for pointers or references.Final Answer:
struct Node { int data; Node* next; }; -> Option CQuick Check:
Pointer to next node = Node* next [OK]
- Using object instead of pointer for next
- Using reference incorrectly for next
- Syntax errors in pointer declaration
struct Node {
int data;
Node* next;
};
int main() {
Node* head = new Node{10, nullptr};
head->next = new Node{20, nullptr};
head->next->next = new Node{30, nullptr};
Node* temp = head;
while (temp != nullptr) {
std::cout << temp->data << " -> ";
temp = temp->next;
}
std::cout << "null";
return 0;
}Solution
Step 1: Trace node creation and linking
Nodes are created with values 10, 20, 30 linked in order: head -> 10 -> 20 -> 30 -> nullptr.Step 2: Trace printing loop
The loop prints each node's data followed by ' -> ', ending with 'null'. Output is "10 -> 20 -> 30 -> null".Final Answer:
10 -> 20 -> 30 -> null -> Option AQuick Check:
Print nodes in order = 10 -> 20 -> 30 -> null [OK]
- Printing nodes in reverse order
- Missing last node in output
- Confusing nullptr with null string
struct Node {
int data;
Node* next;
};
int main() {
Node* head = new Node{1, nullptr};
head->next = new Node{2, nullptr};
head->next->next = new Node{3, nullptr};
return 0;
}Solution
Step 1: Check node creation and linking
head is created with data 1, next nullptr. Then head->next is assigned new node with data 2, next nullptr.Step 2: Assign head->next->next
head->next is not nullptr, so assigning head->next->next to new node with data 3 is valid.Final Answer:
No error, code runs correctly -> Option DQuick Check:
Nodes linked properly, no nullptr dereference [OK]
- Assuming head->next is nullptr before assignment
- Confusing pointer initialization
- Thinking struct definition is wrong
appendNode that adds a new node with given data at the end of a singly linked list. Which of the following implementations correctly appends a node?void appendNode(Node*& head, int value) {
Node* newNode = new Node{value, nullptr};
if (head == nullptr) {
head = newNode;
} else {
Node* temp = head;
while (temp->next != nullptr) {
temp = temp->next;
}
temp->next = newNode;
}
}Solution
Step 1: Check new node creation
New node is created with given value and next set to nullptr, which is correct for end node.Step 2: Check list empty and non-empty cases
If head is nullptr, head is updated to new node. Otherwise, code traverses to last node and sets its next to new node.Final Answer:
Correctly appends node at end -> Option BQuick Check:
Traverse to last node and link new node [OK]
- Not updating head when list is empty
- Wrong loop condition causing infinite loop
- Forgetting to set new node's next to nullptr
Ready to prove it?
Pass the test and this pattern moves unknown
