HOWTO · C++
How to Check if Linked List Is Empty in C++
This tutorial exemplifies how to check if a linked list is empty in C++.
On this page
A linked list stores elements in nodes connected by pointers; it does not behave like an array whose elements occupy indexed positions. To check whether a list has any data nodes, use the invariant of its representation. A head pointer, a sentinel node, and the standard-library container each have a different appropriate check. A node’s payload, including a value of zero, does not tell you whether the list contains elements. (C++)
Check a Linked List’s Empty State
First identify how the list represents its start and how insertion and removal maintain that representation. A check is reliable only while those operations preserve the corresponding invariant. For a custom list, do not assume that a pointer is null or self-linked unless the implementation guarantees it. These checks take constant time because they inspect one pointer or call the container member that reports whether it stores elements; they do not traverse the nodes.
Before running the sample, note that Node contains a payload and a link, and main creates one node, assigns its fields, and points head at it. The branch tests only the pointer. This check is independent of the payload and does not walk the chain; it is suitable when the list invariant says the head points to its first data node. Keep the node alive while the head refers to it.
Run this example:
#include <cstddef>
#include <iostream>
struct Node {
int data;
Node* next;
};
int main() {
Node first;
first.data = 7;
first.next = NULL;
Node* head = &first;
if (head != NULL) {
std::cout << "The list has a node.\n";
}
}
The list has a node.
Use the sections below to select a condition for your representation.
Check a List Without a Sentinel Node
In a conventional singly linked list without a sentinel, the head points to the first data node. The list is empty when that pointer is NULL; a non-null head means at least one node is present. In a function that receives a pointer to the head, test the head itself before accessing any node fields. Dereferencing a null head is undefined behavior.
For example, the condition is head == NULL. When the list is populated, the same check is false regardless of whether the first node stores 0, a negative number, or another value. Payload values describe data, not list structure. The check is constant time and needs no special value reserved to signal emptiness.
This complete example checks both states by changing only the head pointer. The node’s fields are assigned separately, so the initialization does not depend on aggregate list initialization.
#include <cstddef>
struct Node {
int data;
Node* next;
};
int main() {
Node first;
first.data = 0;
first.next = NULL;
Node* head = NULL;
const bool no_nodes = head == NULL;
head = &first;
const bool has_node = head != NULL;
return (no_nodes && has_node) ? 0 : 1;
}
Check a Sentinel-Based List
Some custom lists keep a sentinel node that is not a data node. The sentinel can remain allocated when the list has no elements, so its existence or payload does not establish whether the list is empty. The links do.
A circular sentinel design commonly uses the invariant that the sentinel’s next pointer points back to the sentinel when there are no data nodes. Under that design, sentinel->next == sentinel is the empty check; with data nodes, the link points to the first data node. A linear sentinel design may instead use a null next pointer when empty, making sentinel->next == NULL the appropriate check. These conditions are alternatives for different designs, not interchangeable tests. Apply the one maintained by the list’s insertion and removal operations.
A sentinel avoids a null head in some operations, but it does not mean every pointer in every list can be dereferenced safely. In particular, ensure the sentinel pointer itself exists before reading its links.
Use the Standard Library’s empty() Member
For a standard-library list, use std::list::empty() (or call values.empty() on a list object). It reports whether the container has elements and does not expose implementation details such as sentinels. Do not apply a custom linked list’s pointer condition to std::list; its representation is managed by the library.
Use the result directly in a condition, such as if (values.empty()). The member is constant time and is clearer than comparing size() with zero when the question is simply whether the container contains elements. For a custom list, choose the check that matches its documented invariant: null head without a sentinel, or the sentinel link used by that implementation.
This selectable example evaluates std::list::empty() before and after inserting an element:
#include <list>
int main() {
std::list<int> values;
const bool initially_empty = values.empty();
values.push_back(5);
const bool populated_after_insert = !values.empty();
return (initially_empty && populated_after_insert) ? 0 : 1;
}