A C++ doubly linked list is a data structure that consists of nodes, where each node contains three elements: a data field, a pointer to the next node, and a pointer to the previous node, allowing traversal in both directions.
Here's a simple C++ code snippet demonstrating the structure of a doubly linked list:
#include <iostream>
class Node {
public:
int data;
Node* next;
Node* prev;
Node(int value) : data(value), next(nullptr), prev(nullptr) {}
};
class DoublyLinkedList {
private:
Node* head;
Node* tail;
public:
DoublyLinkedList() : head(nullptr), tail(nullptr) {}
void append(int value) {
Node* newNode = new Node(value);
if (!head) {
head = tail = newNode;
} else {
tail->next = newNode;
newNode->prev = tail;
tail = newNode;
}
}
// Other methods such as display, delete, etc. can be added here
};
int main() {
DoublyLinkedList dll;
dll.append(1);
dll.append(2);
dll.append(3);
return 0;
}
What is a Doubly Linked List?
A doubly linked list is a data structure that consists of a collection of nodes, where each node contains a data field and two pointers—one pointing to the next node and one pointing to the previous node. This unique arrangement enables bidirectional traversal, allowing users to navigate both forward and backward through the list.
Unlike a singly linked list, which only allows navigation in one direction (from head to tail), a doubly linked list provides more flexibility in various operations such as insertion, deletion, and traversal.
Characteristics
- Bidirectional Navigation: Each node contains a pointer to both its next node and its previous node. This means you can traverse the list in either direction.
- Dynamic Size: The list can grow or shrink as needed. When you add or remove nodes, the memory is allocated and deallocated automatically, making it memory-efficient.
- Node Structure: Each node consists of three components:
- `data`: Contains the value or information the node holds.
- `next`: Points to the next node in the sequence.
- `prev`: Points to the previous node, enabling backward traversal.

Basic Structure of a Doubly Linked List in C++
The C++ implementation of a doubly linked list begins with defining a node structure. Here is a simple representation:
struct Node {
int data;
Node* next;
Node* prev;
};
In this structure, we have:
- An integer `data` that holds the value.
- A pointer `next` that points to the following node.
- A pointer `prev` that points to the previous node.
Next, we define the main DoublyLinkedList class, which contains a `head` and `tail` pointer to facilitate easy access to the first and last nodes:
class DoublyLinkedList {
private:
Node* head;
Node* tail;
public:
DoublyLinkedList();
void insertAtBeginning(int data);
void insertAtEnd(int data);
// other functions like delete, display, etc.
};
The `head` pointer marks the start of the list, while the `tail` can be used to quickly access the end.

Common Operations on a Doubly Linked List
Insertion
Insert at the Beginning
Inserting a node at the beginning of the list is straightforward. The function can be implemented as follows:
void DoublyLinkedList::insertAtBeginning(int data) {
Node* newNode = new Node();
newNode->data = data;
newNode->next = head;
newNode->prev = nullptr;
if (head != nullptr) {
head->prev = newNode;
}
head = newNode;
}
In this function:
- A new node is created and its `data` is set.
- The `next` pointer of the new node is set to the current head.
- If the list is not empty, the previous head node's `prev` pointer is updated to point to the new node.
- Finally, the `head` pointer is updated to the new node.
Insert at the End
To insert at the end, you can use the following implementation:
void DoublyLinkedList::insertAtEnd(int data) {
Node* newNode = new Node();
newNode->data = data;
newNode->next = nullptr;
if (head == nullptr) {
newNode->prev = nullptr;
head = newNode;
return;
}
Node* lastNode = head;
while (lastNode->next != nullptr) {
lastNode = lastNode->next;
}
lastNode->next = newNode;
newNode->prev = lastNode;
}
In this implementation:
- A new node is created similarly to the previous function.
- If the list is empty, the new node becomes the head.
- If the list contains nodes, we traverse to the last node and set its `next` to the new node, linking the new node's `prev` pointer accordingly.
Deletion
Delete from the Beginning
You can delete a node from the beginning of the doubly linked list as follows:
void DoublyLinkedList::deleteFromBeginning() {
if (head == nullptr) return;
Node* temp = head;
head = head->next;
if (head != nullptr) {
head->prev = nullptr;
}
delete temp;
}
- The function checks if the head is `nullptr` (i.e., the list is empty). If it is, the function returns.
- If the list is not empty, the code stores the current head in a temporary pointer, updates the head to the next node, and adjusts the `prev` pointer of the new head.
- Finally, it deletes the old head node, ensuring proper memory management.
Delete from the End
To remove a node from the end, the following function is used:
void DoublyLinkedList::deleteFromEnd() {
if (head == nullptr) return;
Node* lastNode = head;
while (lastNode->next != nullptr) {
lastNode = lastNode->next;
}
if (lastNode->prev != nullptr) {
lastNode->prev->next = nullptr;
} else {
head = nullptr; // List had only one node
}
delete lastNode;
}
In this case:
- The function again checks if the list is empty and returns if true.
- The code navigates to the last node.
- If the last node has a previous node, we adjust its `next` pointer to `nullptr`.
- If it's the only node in the list, we set the `head` to `nullptr`.

Traversing a Doubly Linked List
Forward Traversal
Traversal of the list can be achieved easily. Here’s how you can display the list in forward direction:
void displayForward() {
Node* node = head;
while (node != nullptr) {
cout << node->data << " ";
node = node->next;
}
}
In this function:
- We start with the `head` node and traverse until we reach a node that points to `nullptr`.
- For each node, we print the contained data.
Backward Traversal
To traverse in reverse order, you can implement it like this:
void displayBackward() {
Node* node = tail;
while (node != nullptr) {
cout << node->data << " ";
node = node->prev;
}
}
- This function begins at the `tail` (the last node) and traverses backwards.
- It prints the data as it moves through the previous nodes until reaching the start of the list.

Practical Applications of a Doubly Linked List
Doubly linked lists have numerous practical applications in computer science and software development, including:
- Navigation Systems: The ability to move both forwards and backward makes doubly linked lists particularly useful in applications like browser history management and undo/redo functionalities in software.
- Memory Management in Operating Systems: Doubly linked lists are frequently employed in various memory management scenarios, such as implementing free lists for memory allocation and deallocation.

Conclusion
Mastering a C++ doubly linked list is critical for every software developer. This data structure not only enhances data management capabilities but also broadens your understanding of more complex data structures. By implementing a doubly linked list and practicing various operations, you'll solidify your knowledge of C++ and data structures in general.

Additional Resources
For further exploration of doubly linked lists and more advanced data structures, consider checking out textbooks on data structures, online tutorials, or video lectures from reputable educational platforms.

Call to Action
Stay updated with our latest posts, where we offer quick, concise tips on C++ commands and data structures. Together, let’s enhance your programming skills!