Home | Projects | Notes > Data Structures & Algorithms > Singly-Linked Lists
A singly linked list is a linear data structure made up of nodes, where each node contains a data value and a pointer to the next node in the sequence. The list is traversed in one direction — from the front to the back — by following these next pointers. It supports dynamic memory usage and is ideal for frequent insertions or deletions at known positions.

Dynamic Size: Easily grows or shrinks without reallocating or copying (unlike arrays).
Efficient Insertion/Deletion: O(1) time to insert or delete at the head (or with a known pointer).
Low Memory Overhead per Element: Requires only one pointer (next) per node.
No Wasted Space: No need to preallocate or resize like arrays.
No Random Access: Accessing the n-th element takes O(n) time; cannot do list[i] like arrays.
Sequential Traversal Only: Cannot traverse backward; no prev pointer.
More Memory per Element Than Arrays: Each node stores a pointer along with data.
Cache Unfriendly: Nodes are not contiguous in memory, leading to poor cache performance compared to arrays or vectors.
Better: Insert/delete at front/back (if back pointer is maintained).
Worse: Random access, cache locality, memory overhead.
slist.hpp)41123
45
6class node7{8public:9 node(int val) : data(val), p_next(nullptr) {}10
11 int data;12 node *p_next;13};14
15class slist16{17public:18 slist() : p_front(nullptr), cnt(0) {}19 ~slist() { clear(); }20 void push_front(const int val);21 void push_back(const int val);22 void insert_at(const int idx, const int val);23 void pop_front();24 void pop_back();25 void erase_at(const int idx);26 void erase_val(const int val);27 int get_at(const int idx) const;28 int find(const int val) const;29 int front() const;30 int back() const;31 int size() const;32 bool empty() const;33 void clear();34 void print() const;35 36private:37 node *p_front;38 int cnt;39};40
41slist.cpp)252123
4void slist::push_front(const int val)5{6 node *p_new = new node(val);7 p_new->p_next = p_front;8 p_front = p_new;9 ++cnt;10}11
12void slist::push_back(const int val)13{14 node *p_new = new node(val);15
16 if (!p_front)17 {18 p_front = p_new;19 }20 else21 {22 node *p_temp = p_front;23
24 while (p_temp->p_next)25 {26 p_temp = p_temp->p_next;27 }28
29 p_temp->p_next = p_new;30 }31
32 ++cnt;33}34
35void slist::insert_at(const int idx, const int val)36{37 if (idx < 0 || idx > cnt)38 {39 return;40 }41
42 if (idx == 0)43 {44 return push_front(val);45 }46
47 node *p_new = new node(val);48 node *p_temp = p_front;49
50 for (int i = 0; i < idx - 1; ++i)51 {52 p_temp = p_temp->p_next;53 }54
55 p_new->p_next = p_temp->p_next;56 p_temp->p_next = p_new;57
58 ++cnt;59}60
61void slist::pop_front()62{63 if (!p_front)64 {65 return;66 }67
68 node *p_temp = p_front;69 p_front = p_front->p_next;70 delete p_temp;71 --cnt;72}73
74void slist::pop_back()75{76 if (!p_front)77 {78 return;79 } 80
81 if (!p_front->p_next)82 {83 delete p_front;84 p_front = nullptr;85 }86 else87 {88 node *p_temp = p_front;89
90 while (p_temp->p_next->p_next)91 {92 p_temp = p_temp->p_next;93 }94
95 delete p_temp->p_next;96 p_temp->p_next = nullptr;97 }98
99 --cnt;100}101
102void slist::erase_at(const int idx)103{104 if (idx < 0 || idx > cnt)105 {106 return;107 }108
109 if (idx == 0)110 {111 return pop_front();112 }113
114 node *p_temp = p_front;115
116 for (int i = 0; i < idx - 1; ++i)117 {118 p_temp = p_temp->p_next;119 }120
121 node *p_del = p_temp->p_next;122 p_temp->p_next = p_temp->p_next->p_next;123 delete p_del;124 --cnt;125}126
127void slist::erase_val(const int val)128{129 if (!p_front)130 {131 return;132 }133
134 if (val == p_front->data)135 {136 pop_front();137 }138
139 node *p_temp = p_front;140
141 while (p_temp->p_next && val != p_temp->p_next->data)142 {143 p_temp = p_temp->p_next;144 }145
146 if (p_temp->p_next)147 {148 node *p_del = p_temp->p_next;149 p_temp->p_next = p_temp->p_next->p_next;150 delete p_del;151 }152
153 --cnt;154}155
156int slist::get_at(const int idx) const157{158 if (idx < 0 || idx >= cnt)159 {160 throw std::out_of_range("Index out of range");161 }162
163 node *p_temp = p_front;164
165 for (int i = 0; i < idx; ++i)166 {167 p_temp = p_temp->p_next;168 }169
170 return p_temp->data;171}172
173int slist::find(const int val) const174{175 node *p_temp = p_front;176 int idx = 0;177
178 while (p_temp)179 {180 if (val == p_temp->data)181 {182 return idx;183 }184
185 p_temp = p_temp->p_next;186 idx++;187 }188
189 return -1;190}191
192int slist::front() const193{194 if (!p_front)195 {196 throw std::runtime_error("List is empty");197 }198
199 return p_front->data;200}201
202int slist::back() const203{204 if (!p_front)205 {206 throw std::runtime_error("List is empty");207 }208
209 node *p_temp = p_front;210
211 while (p_temp->p_next)212 {213 p_temp = p_temp->p_next;214 }215
216 return p_temp->data;217}218
219int slist::size() const220{221 return cnt;222}223
224bool slist::empty() const225{226 return 0 == cnt;227}228
229void slist::clear()230{231 while (p_front)232 {233 node *p_temp = p_front;234 p_front = p_front->p_next;235 delete p_temp;236 }237
238 cnt = 0;239}240
241void slist::print() const242{243 node *p_temp = p_front;244
245 while (p_temp)246 {247 std::cout << p_temp->data << " -> ";248 p_temp = p_temp->p_next;249 }250
251 std::cout << "null" << std::endl;252}40123
4int main(int argc, char *argv[])5{6 slist sl;7
8 sl.push_front(1);9 sl.push_back(2);10 sl.push_back(3);11 sl.push_back(4);12 sl.push_back(5);13 sl.push_back(6);14 sl.print(); // 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null15
16 sl.pop_front();17 sl.print(); // 2 -> 3 -> 4 -> 5 -> 6 -> null18 sl.pop_back();19 sl.print(); // 2 -> 3 -> 4 -> 5 -> null20
21 sl.insert_at(0, 1); 22 sl.print(); // 1 -> 2 -> 3 -> 4 -> 5 -> null23 sl.erase_at(1);24 sl.print(); // 1 -> 3 -> 4 -> 5 -> null25 sl.erase_val(3);26 sl.print(); // 1 -> 4 -> 5 -> null27
28 std::cout << sl.find(4) << std::endl; // 129 std::cout << sl.empty() << std::endl; // 030 std::cout << sl.size() << std::endl; // 331
32 std::cout << sl.front() << std::endl; // 133 std::cout << sl.back() << std::endl; // 534 std::cout << sl.get_at(1) << std::endl; // 435
36 sl.clear();37 sl.print(); // null38
39 return 0;40}1311 -> 2 -> 3 -> 4 -> 5 -> 6 -> null22 -> 3 -> 4 -> 5 -> 6 -> null32 -> 3 -> 4 -> 5 -> null41 -> 2 -> 3 -> 4 -> 5 -> null51 -> 3 -> 4 -> 5 -> null61 -> 4 -> 5 -> null71809310111512413null