Loading learning content...
In chemistry, the atom is the fundamental unit of matter—everything from water to steel to human cells is composed of atoms bonded together. In the world of linked data structures, the node plays an analogous role: it is the irreducible building block from which all linked structures—singly linked lists, doubly linked lists, trees, graphs—are composed.
Understanding nodes deeply is not optional. Every operation you perform on a linked list—insertion, deletion, traversal, reversal—is fundamentally an operation on nodes and the connections between them. If your mental model of a node is hazy, every linked structure problem will feel harder than it should. If your model is precise, linked structures become intuitive and even elegant.
By the end of this page, you will understand exactly what a node is, what it contains, why it exists, and how it differs from the elements in an array. You'll develop the vocabulary and mental imagery to reason about linked structures with confidence.
A node is a self-contained unit of data that holds two fundamental pieces of information:
Data (or Value): The actual information being stored—an integer, a string, an object, or any other type of data relevant to your application.
Link(s) (or Pointer(s)/Reference(s)): The address of, or connection to, one or more other nodes in the structure.
This dual nature—data plus connection—is what distinguishes a node from a simple variable or array element. A variable just holds data. An array element holds data at a predictable position. But a node holds data AND knows where to find other nodes.
A node is like an envelope that contains both a message (the data) and a forwarding address (the link to the next node). You can't understand what's inside without opening it, and you can't find the next envelope without reading the forwarding address inside.
Visual Representation:
The standard way to visualize a node is as a box divided into compartments:
+--------+--------+
| Data | Next |
+--------+--------+
| 42 | •———→ (points to another node)
+--------+--------+
The first compartment holds the payload—the actual value you're storing. The second compartment holds the reference to the next node. In this simple singly-linked model, each node points to exactly one other node (or to nothing, which we'll discuss later).
Nodes Are Not Array Indices:
In an array, the position of each element is implicit. array[5] means "the element at position 5," calculated directly from the base address plus an offset. No element in the array "knows" about its neighbors—the array's contiguous layout and indexing system handle navigation.
In a linked structure, there are no indices. If you want to find the 5th node, you must start at the first node and follow 4 links. Each node only knows about its immediate successor(s)—the structure emerges from the connections, not from any external numbering system.
| Characteristic | Array Element | Node |
|---|---|---|
| Contains | Data only | Data + Link(s) |
| Location determined by | Index/offset calculation | Following references from other nodes |
| Knows about neighbors | No (implicit from index) | Yes (explicit via pointers) |
| Memory layout | Contiguous with other elements | Can be anywhere in memory |
| Access time to arbitrary element | O(1) via index | O(n) by traversal |
| Overhead | None (just the data) | Extra space for pointer(s) |
Nodes exist because arrays, for all their speed and simplicity, have fundamental limitations that become painful in certain scenarios. Understanding why nodes were invented helps you appreciate when they're the right tool.
The Problems Nodes Solve:
The Trade-Off:
Nodes don't replace arrays—they complement them. The price you pay for node-based flexibility is:
But when your use case requires frequent insertions and deletions, when the size of your data is unpredictable, or when you need to model non-linear relationships, nodes become not just useful but essential.
Think of an array as a row of numbered lockers in a gym—accessing any locker is instant because you know exactly where locker #50 is. Nodes are more like a treasure hunt: each clue (node) tells you where to find the next clue. You can easily add or remove clues anywhere in the chain without moving all the others, but you can't skip directly to clue #50 without following the chain from the beginning.
The concept of a node is not limited to linked lists. The same fundamental idea—a container holding data and references to other containers—appears throughout computer science:
Singly Linked List Node:
next → points to the successor nodeDoubly Linked List Node:
prev → points to the predecessor, next → points to the successorBinary Tree Node:
left → points to left child, right → points to right childGraph Node (Vertex):
N-ary Tree Node:
| Data Structure | Number of Links per Node | Link Names |
|---|---|---|
| Singly Linked List | 1 | next |
| Doubly Linked List | 2 | prev, next |
| Binary Tree | 2 | left, right |
| Binary Search Tree | 2 | left, right (with ordering property) |
| N-ary Tree | Variable (0 to n) | children (usually a list) |
| Graph (Adjacency List) | Variable | neighbors or edges |
The Unifying Principle:
Regardless of the structure, the node concept remains consistent:
When you truly understand nodes in linked lists, you've built the mental infrastructure to understand trees, graphs, and every other linked structure. They differ only in the number and semantics of the links, not in the fundamental concept.
Linked lists are the simplest node-based structure: each node has exactly one link (forward). Trees add one more link (and hierarchy). Graphs add arbitrary numbers of links. Build your understanding from simple to complex, and each level becomes easier.
Let's build a precise mental model of what happens at the conceptual level when you create and connect nodes.
Step 1: Create a Node
When you create a node, the system allocates a chunk of memory somewhere. This chunk is large enough to hold:
The node exists at a specific memory address. This address is just a number—like a street address for a house.
Step 2: Store Data
You assign a value to the node's data field. Now the node "contains" that value.
Step 3: Store a Link
The link field stores the address of another node. It literally holds the number that represents where the next node lives in memory.
Example with Concrete Addresses:
Memory Address Content+---------------+--------------+| 0x1000 | Data: 10 | <- Node A lives here| | Next: 0x1020 | <- Points to Node B's address+---------------+--------------+| 0x1020 | Data: 20 | <- Node B lives here| | Next: 0x1050 | <- Points to Node C's address+---------------+--------------+| 0x1050 | Data: 30 | <- Node C lives here| | Next: null | <- End of list (no next node)+---------------+--------------+ Traversal:Start at 0x1000 (Node A with value 10)Read next pointer: 0x1020Jump to 0x1020 (Node B with value 20)Read next pointer: 0x1050Jump to 0x1050 (Node C with value 30)Read next pointer: nullStop — end of listKey Observations:
Addresses Are Not Sequential: Node A is at 0x1000, Node B at 0x1020, Node C at 0x1050. These addresses are not adjacent like array elements would be. The nodes could be anywhere in memory.
The Structure Is In the Pointers: The fact that A connects to B connects to C creates a sequence. But this sequence exists only because of the pointer values stored in each node. Rearrange the memory, but keep the pointers consistent, and the logical sequence remains the same.
No External Index Exists: There's no nodes[0], nodes[1], nodes[2] array somewhere tracking these. The only way to reach Node C is to start at Node A and follow the chain.
Null Marks the Boundary: The null pointer in Node C indicates there is no "next" node. This is how the structure communicates "this is the end."
In high-level languages like Python or Java, you never see actual memory addresses like 0x1000. The language runtime manages this for you. But conceptually, the reference/pointer still stores a way to locate the next node. The model holds even when the details are abstracted.
One of the most powerful properties of nodes is their independence. Unlike array elements, which are born together in a single allocation and die together when the array is destroyed, nodes have individual lifecycles.
Creating Nodes Independently:
Destroying Nodes Independently:
The Power of Dynamic Allocation:
Memory Fragmentation Trade-Off:
This independence comes with a downside: nodes are typically scattered throughout memory, not packed together. This fragmentation means:
Worse Cache Performance: Modern CPUs load memory in chunks (cache lines). Adjacent array elements often share a cache line, so iterating is fast. Nodes at random addresses cause cache misses on nearly every access.
Memory Overhead Per Node: Each node carries the cost of its pointer field(s). For small data (like a single integer), the pointer might double the memory used compared to an array.
Allocation Overhead: Requesting memory for each node individually incurs overhead compared to a single large block allocation.
Despite these trade-offs, node-based structures remain the right choice when flexibility outweighs raw traversal speed—and in many applications, it does.
A node can be thought of as a self-contained package of information and connectivity. This encapsulation provides several benefits:
1. Modularity:
Each node is a complete unit. It doesn't depend on any external numbering scheme or on being at a particular memory location. You can move a node's data and links to a different memory address (updating incoming pointers accordingly), and the structure's logic remains unchanged.
2. Composability:
Nodes can be combined in arbitrary ways. The same type of node that forms a linked list can also be used to build a tree (by adding a second pointer) or a graph (by adding a list of pointers). The node abstraction is reusable.
3. Local Knowledge:
A node knows only about itself and its immediate neighbors (the nodes it points to). It doesn't know:
This local knowledge is both a strength and a limitation. It enables efficient local operations (insert/delete nearby) but makes global operations (find the kth element) slower.
Nodes are intentionally simple—almost "dumb." They don't contain complex logic or behavioral methods. They're pure data containers with links. This simplicity is a feature: it makes nodes predictable, debuggable, and easy to reason about.
Node as a Class/Struct:
In object-oriented or structured programming, a node is typically implemented as a class (or struct) with fields:
class ListNode:
def __init__(self, value):
self.value = value # The data
self.next = None # Reference to the next node
class ListNode {
int value;
ListNode next;
ListNode(int value) {
this.value = value;
this.next = null;
}
}
struct ListNode {
int value;
ListNode* next;
ListNode(int val) : value(val), next(nullptr) {}
};
In all these cases, the pattern is identical: a container with a data field and one or more reference fields. The language's syntax varies, but the concept is universal.
Mastering linked structures requires a mental shift from index-based thinking to node-based thinking. Here's what that shift looks like:
Index-Based Thinking (Arrays):
array[5]Node-Based Thinking (Linked Structures):
index < length, you check current != null.The more linked list problems you solve, the more natural node-based thinking becomes. Initially, it feels awkward compared to arrays. With practice, you'll start seeing node-pointer manipulation as elegant and intuitive. The shift is worth the investment.
As you learn about nodes, be aware of these common misconceptions that trip up learners:
Misconception 1: "Nodes are stored in order in memory"
False. The logical order (A → B → C) has nothing to do with memory addresses. Node B might be at a lower address than Node A. The sequence exists only because of the pointers, not because of any physical arrangement.
Misconception 2: "The pointer stores the entire next node"
False. The pointer stores only the address of the next node—typically 4 or 8 bytes regardless of how large the node's data is. The actual node data lives at that address; the pointer just says where to find it.
Misconception 3: "Linked lists are always better than arrays for insertion"
Partially true. Insertion at a known position (i.e., you already have a pointer to the node) is O(1). But finding that position is O(n). If you need to insert after the 500th element, you still must traverse 499 nodes first. Arrays require fewer operations to reach position 500 (O(1) indexing).
Misconception 4: "Null is a special node"
False. Null is not a node—it's the absence of a node. It's a special value indicating "there's nothing here." You cannot dereference null (access its data or pointer) without causing an error.
Misconception 5: "Two variables pointing to the same node create two nodes"
False. If ptr1 and ptr2 both hold the same memory address, they both reference the same node. Changes made via ptr1 are visible via ptr2. There's still only one node.
When two variables point to the same node, modifying the node through one variable affects what you see through the other. This is called aliasing and is a source of many bugs. Always be conscious of which variables share node references.
Let's consolidate everything we've learned about nodes:
What's Next:
Now that you understand what a node is, we need to go deeper into the mechanism that connects them: pointers and references. The next page will explore exactly what a pointer is, how references work in different languages, and how to think about memory addresses at a conceptual level—the foundation for all linked structure manipulation.
You now have a solid understanding of what a node is and why this simple concept is the foundation of all linked data structures. With this mental model in place, you're ready to explore how nodes connect through pointers and references.