Doubly Linked List using Sentinel Nodes
Last Updated :
28 Mar, 2024
In the case of the simple doubly linked list, if we have to perform the insertion or deletion operation at the starting of the doubly linked list, end of the doubly linked list, or in between the starting and end nodes for each, we require to check different condition that makes the algorithm complex so to solve this problem we can use doubly linked list along with the sentinel nodes.
What is a sentinel node?
Sentinel nodes are specially designed nodes that do not hold or refer to any data of the doubly linked list (that data structure).
To make insertion and deletion operations in a doubly-linked list simple, we have to add one sentinel node at the beginning of the doubly linked list and one at the end of the doubly linked list, as shown in the below diagram.

Doubly linked list with sentinel nodes
As shown above, each node other than the sentinel nodes contains the pointer to the previous and next node along with data.
Advantage of Sentinel node:
The most significant advantage of using the sentinel nodes in the doubly linked list:
- By adding the sentinel nodes to the doubly linked list now for the deletion or insertion at the beginning, end or in between the beginning and end nodes of the linked list, we do not need to write the different conditions for each one.Â
- All these operations can be done as the deletion or insertion between the beginning and end node of a doubly linked list.
Structure of a Doubly-Linked List using sentinel nodes:
The structure of each node and the creation of the new node in a doubly-linked list with sentinel nodes are the same as the simple doubly-linked list, as shown below.
C++
// Each node contains the data,
// previous node pointer and
// the next node pointer
struct node {
int data;
struct node* next;
struct node* pre;
};
// To create a node, first define the node pointer
// and than assign the memory required by the node
// and return the node
struct node* createnode()
{
struct node* t;
t = (struct node*)malloc(sizeof(struct node));
return (t);
}
Java
// Each node contains the data,
// previous node pointer and
// the next node pointer
static class Node {
int data;
node next;
node pre;
}
// To create a node, first define the node pointer
// and than assign the memory required by the node
// and return the pointer
Node createnode()
{
Node node = new Node();
retutn node;
}
Python
# Each node contains the data,
# previous node pointer and
# the next node pointer
class Node:
def __init__(self, data):
self.data = data
self.next = None
self.pre = None
# To create a node, first define the node pointer
# and than assign the memory required by the node
# and return the pointer
def createNode():
return Node(None)
C#
// Each node contains the data,
// previous node pointer and
// the next node pointer
public static class Node {
public int data;
public Node next;
public Node pre;
}
// To create a node, first define the node pointer
// and than assign the memory required by the node
// and return the pointer
public static Node CreateNode()
{
Node node = new Node();
return node;
}
// This code is contributed by akashish__
JavaScript
// Each node contains the data,
// previous node pointer and
// the next node pointer
class Node {
constructor(data) {
this.data = data;
this.next = null;
this.pre = null;
}
}
// To create a node, first define the node pointer
// and than assign the memory required by the node
// and return the node
function createNode() {
return new Node();
}
Operations on a doubly-linked list using Sentinel Nodes:
The common operations in a doubly-linked list are:
- Insert new node
- Delete existing node
- Display all the nodes’ dataÂ
1. Insert a new node in a Doubly-Linked List using Sentinel Nodes
Insertion of a new node in a doubly-linked list can be done in three ways, but as we have used the sentinel node in the doubly linked list, so we do not have to write a different algorithm for each case we have to give the location of the node after which we have to add the new node to the linked list as shown in the code.
- Insert a new node at the beginning of the doubly-linked list
In this, we are adding the new node just after the head sentinel node. So basically, we are adding the new node at the beginning of the doubly linked list. Still, it will behave as the addition of a node between the beginning and end node of the linked list due to the sentinel node.

Insertion of node at beginning of the doubly linked list
Below is the code implemention to Insert a new node at the beginning of the doubly-linked list:
C++
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* prev;
Node* next;
Node(int data, Node* prev, Node* next) {
this->data = data;
this->prev = prev;
this->next = next;
}
};
class DoublyLinkedList {
private:
Node* sentinel;
public:
DoublyLinkedList() {
sentinel = new Node(0, nullptr, nullptr);
sentinel->prev = sentinel;
sentinel->next = sentinel;
}
void insertAtBeginning(int data) {
Node* newNode = new Node(data, sentinel, sentinel->next);
sentinel->next->prev = newNode;
sentinel->next = newNode;
}
void printList() {
Node* currentNode = sentinel->next;
while (currentNode != sentinel) {
cout << currentNode->data << " ";
currentNode = currentNode->next;
}
cout << endl;
}
};
int main() {
DoublyLinkedList my_list;
my_list.insertAtBeginning(5);
my_list.insertAtBeginning(10);
my_list.insertAtBeginning(15);
my_list.printList();
return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *prev;
struct Node *next;
} Node;
typedef struct DoublyLinkedList {
Node *sentinel;
} DoublyLinkedList;
void insertAtBeginning(DoublyLinkedList *list, int data) {
Node *newNode = (Node*) malloc(sizeof(Node));
newNode->data = data;
newNode->prev = list->sentinel;
newNode->next = list->sentinel->next;
list->sentinel->next->prev = newNode;
list->sentinel->next = newNode;
}
void printList(DoublyLinkedList *list) {
Node *currentNode = list->sentinel->next;
while (currentNode != list->sentinel) {
printf("%d ", currentNode->data);
currentNode = currentNode->next;
}
printf("\n");
}
int main() {
DoublyLinkedList *my_list = (DoublyLinkedList*) malloc(sizeof(DoublyLinkedList));
my_list->sentinel = (Node*) malloc(sizeof(Node));
my_list->sentinel->data = 0;
my_list->sentinel->prev = my_list->sentinel;
my_list->sentinel->next = my_list->sentinel;
insertAtBeginning(my_list, 5);
insertAtBeginning(my_list, 10);
insertAtBeginning(my_list, 15);
printList(my_list);
return 0;
}
Java
class Node {
public $data;
public $prev;
public $next;
public function __construct($data, $prev, $next) {
$this->data = $data;
$this->prev = $prev;
$this->next = $next;
}
}
class DoublyLinkedList {
private $sentinel;
public function __construct() {
$this->sentinel = new Node(0, null, null);
$this->sentinel->prev = $this->sentinel;
$this->sentinel->next = $this->sentinel;
}
public function insertAtBeginning($data) {
$newNode = new Node($data, $this->sentinel, $this->sentinel->next);
$this->sentinel->next->prev = $newNode;
$this->sentinel->next = $newNode;
$this->updateSentinelData();
}
private function updateSentinelData() {
// update sentinel data if needed
}
public function traverse() {
$currentNode = $this->sentinel->next;
while ($currentNode != $this->sentinel) {
echo $currentNode->data . "\n";
$currentNode = $currentNode->next;
}
}
}
$my_list = new DoublyLinkedList();
$my_list->insertAtBeginning(5);
$my_list->insertAtBeginning(10);
$my_list->insertAtBeginning(15);
$my_list->traverse();
C#
using System;
public class Node {
public int data;
public Node prev;
public Node next;
public Node(int data, Node prev, Node next) {
this.data = data;
this.prev = prev;
this.next = next;
}
}
public class DoublyLinkedList {
private Node sentinel;
public DoublyLinkedList() {
sentinel = new Node(0, null, null);
sentinel.prev = sentinel;
sentinel.next = sentinel;
}
public void insertAtBeginning(int data) {
Node newNode = new Node(data, sentinel, sentinel.next);
sentinel.next.prev = newNode;
sentinel.next = newNode;
}
public void printList() {
Node currentNode = sentinel.next;
while (currentNode != sentinel) {
Console.Write(currentNode.data + " ");
currentNode = currentNode.next;
}
Console.WriteLine();
}
}
class Program {
static void Main(string[] args) {
DoublyLinkedList my_list = new DoublyLinkedList();
my_list.insertAtBeginning(5);
my_list.insertAtBeginning(10);
my_list.insertAtBeginning(15);
my_list.printList();
}
}
JavaScript
class Node {
constructor(data, prev, next) {
this.data = data;
this.prev = prev;
this.next = next;
}
}
class DoublyLinkedList {
constructor() {
this.sentinel = new Node(0, null, null);
this.sentinel.prev = this.sentinel;
this.sentinel.next = this.sentinel;
}
insertAtBeginning(data) {
const newNode = new Node(data, this.sentinel, this.sentinel.next);
this.sentinel.next.prev = newNode;
this.sentinel.next = newNode;
}
printList() {
let currentNode = this.sentinel.next;
while (currentNode !== this.sentinel) {
console.log(currentNode.data);
currentNode = currentNode.next;
}
}
}
const my_list = new DoublyLinkedList();
my_list.insertAtBeginning(5);
my_list.insertAtBeginning(10);
my_list.insertAtBeginning(15);
my_list.printList();
Python3
class Node:
def __init__(self, data=None, prev=None, next=None):
self.data = data
self.prev = prev
self.next = next
class DoublyLinkedList:
def __init__(self):
self.sentinel = Node(data=None, prev=None, next=None)
self.sentinel.prev = self.sentinel
self.sentinel.next = self.sentinel
def insert_at_beginning(self, data):
new_node = Node(data=data, prev=self.sentinel, next=self.sentinel.next)
self.sentinel.next.prev = new_node
self.sentinel.next = new_node
self.update_sentinel_data()
def update_sentinel_data(self):
# update sentinel data if needed
pass
# create a new DoublyLinkedList object
my_list = DoublyLinkedList()
# insert some values at the beginning of the list
my_list.insert_at_beginning(5)
my_list.insert_at_beginning(10)
my_list.insert_at_beginning(15)
# print the list
current_node = my_list.sentinel.next
while current_node != my_list.sentinel:
print(current_node.data)
current_node = current_node.next
- Insert a new node at a given position in the linked list
As shown in the given below diagram, we are adding a new node in the middle of the linked list.
Â

Insertion of node at a given position in the doubly linked list
Below is the code implementation to Insert a new node at a given position in the linked list:
C++
#include <iostream>
using namespace std;
class ListNode {
public:
int val;
ListNode* next;
ListNode(int val = 0, ListNode* next = nullptr) {
this->val = val;
this->next = next;
}
};
class LinkedList {
private:
ListNode* head;
ListNode* tail;
public:
LinkedList() {
head = new ListNode();
tail = new ListNode();
head->next = tail;
}
void InsertAtPosition(int val, int pos) {
ListNode* currNode = head;
for (int i = 0; i < pos; i++) {
if (currNode->next == tail) {
if (i == pos - 1) {
break;
} else {
cout << "Position out of range" << endl;
return;
}
}
currNode = currNode->next;
}
ListNode* newNode = new ListNode(val);
newNode->next = currNode->next;
currNode->next = newNode;
}
void PrintList() {
ListNode* currNode = head->next;
while (currNode != tail) {
cout << currNode->val << " -> ";
currNode = currNode->next;
}
cout << "null" << endl;
}
};
int main() {
LinkedList my_list;
my_list.InsertAtPosition(1, 1);
my_list.InsertAtPosition(3, 2);
my_list.InsertAtPosition(2, 2);
my_list.PrintList();
return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int val;
struct ListNode* next;
};
struct LinkedList {
struct ListNode* head;
struct ListNode* tail;
};
void insert_at_position(struct LinkedList* list, int val, int pos) {
struct ListNode* new_node = (struct ListNode*) malloc(sizeof(struct ListNode));
new_node->val = val;
struct ListNode* curr_node = list->head;
for (int i = 0; i < pos; i++) {
if (curr_node->next == list->tail) {
if (i == pos - 1) {
break;
} else {
printf("Position out of range\n");
return;
}
}
curr_node = curr_node->next;
}
new_node->next = curr_node->next;
curr_node->next = new_node;
}
void print_list(struct LinkedList* list) {
struct ListNode* curr_node = list->head->next;
while (curr_node != list->tail) {
printf("%d -> ", curr_node->val);
curr_node = curr_node->next;
}
printf("null\n");
}
int main() {
struct LinkedList my_list;
my_list.head = (struct ListNode*) malloc(sizeof(struct ListNode));
my_list.tail = (struct ListNode*) malloc(sizeof(struct ListNode));
my_list.head->next = my_list.tail;
insert_at_position(&my_list, 1, 1);
insert_at_position(&my_list, 3, 2);
insert_at_position(&my_list, 2, 2);
print_list(&my_list);
return 0;
}
Java
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
class LinkedList {
ListNode head;
ListNode tail;
public LinkedList() {
head = new ListNode();
tail = new ListNode();
head.next = tail;
}
public void insertAtPosition(int val, int pos) {
ListNode newNode = new ListNode(val);
ListNode currNode = head;
for (int i = 0; i < pos; i++) {
if (currNode.next == tail) {
if (i == pos - 1) {
break;
} else {
throw new IndexOutOfBoundsException("Position out of range");
}
}
currNode = currNode.next;
}
newNode.next = currNode.next;
currNode.next = newNode;
}
public void printList() {
ListNode currNode = head.next;
while (currNode != tail) {
System.out.print(currNode.val + " -> ");
currNode = currNode.next;
}
System.out.println("null");
}
}
public class Main {
public static void main(String[] args) {
LinkedList myLinkedList = new LinkedList();
myLinkedList.insertAtPosition(1, 1);
myLinkedList.insertAtPosition(3, 2);
myLinkedList.insertAtPosition(2, 2);
myLinkedList.printList();
}
}
C#
using System;
public class ListNode
{
public int Val;
public ListNode Next;
public ListNode(int val = 0, ListNode next = null)
{
Val = val;
Next = next;
}
}
public class LinkedList
{
private ListNode head;
private ListNode tail;
public LinkedList()
{
head = new ListNode();
tail = new ListNode();
head.Next = tail;
}
public void InsertAtPosition(int val, int pos)
{
ListNode currNode = head;
for (int i = 0; i < pos; i++)
{
if (currNode.Next == tail)
{
if (i == pos - 1)
{
break;
}
else
{
Console.WriteLine("Position out of range");
return;
}
}
currNode = currNode.Next;
}
ListNode newNode = new ListNode(val);
newNode.Next = currNode.Next;
currNode.Next = newNode;
}
public void PrintList()
{
ListNode currNode = head.Next;
while (currNode != tail)
{
Console.Write(currNode.Val + " -> ");
currNode = currNode.Next;
}
Console.Write("null\n");
}
}
class Program
{
static void Main(string[] args)
{
LinkedList my_list = new LinkedList();
my_list.InsertAtPosition(1, 1);
my_list.InsertAtPosition(3, 2);
my_list.InsertAtPosition(2, 2);
my_list.PrintList();
}
}
JavaScript
class ListNode {
constructor(val = 0, next = null) {
this.val = val;
this.next = next;
}
}
class LinkedList {
constructor() {
this.head = new ListNode();
this.tail = new ListNode();
this.head.next = this.tail;
}
insertAtPosition(val, pos) {
let currNode = this.head;
for (let i = 0; i < pos; i++) {
if (currNode.next === this.tail) {
if (i === pos - 1) {
break;
} else {
console.log("Position out of range");
return;
}
}
currNode = currNode.next;
}
let newNode = new ListNode(val);
newNode.next = currNode.next;
currNode.next = newNode;
}
printList() {
let currNode = this.head.next;
while (currNode !== this.tail) {
console.log(currNode.val + " -> ");
currNode = currNode.next;
}
console.log("null");
}
}
let my_list = new LinkedList();
my_list.insertAtPosition(1, 1);
my_list.insertAtPosition(3, 2);
my_list.insertAtPosition(2, 2);
my_list.printList();
Python3
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class LinkedList:
def __init__(self):
self.head = ListNode()
self.tail = ListNode()
self.head.next = self.tail
def insert_at_position(self, val, pos):
new_node = ListNode(val)
curr_node = self.head
for i in range(pos):
if curr_node.next == self.tail:
if i == pos - 1:
break
else:
raise Exception("Position out of range")
curr_node = curr_node.next
new_node.next = curr_node.next
curr_node.next = new_node
def print_list(self):
curr_node = self.head.next
while curr_node != self.tail:
print(curr_node.val, end=" -> ")
curr_node = curr_node.next
print("null")
# Example usage
my_list = LinkedList()
my_list.insert_at_position(1, 1)
my_list.insert_at_position(3, 2)
my_list.insert_at_position(2, 2)
my_list.print_list()
- Insert a new node at the end of the doubly linked list
In this, we are adding the new node just before the tail sentinel node. So basically, we are adding the new node at the end of the doubly linked list. Still, it will behave as the addition of a node in between the beginning and end node of the linked list due to the sentinel node.

Insertion of node at end of the doubly linked list
Below is the code implementation to Insert a new node at the end of the doubly linked list:
C++
#include <iostream>
using namespace std;
// Define the doubly linked list node
class Node {
public:
int data;
Node* prev;
Node* next;
Node(int data) {
this->data = data;
prev = NULL;
next = NULL;
}
};
// Define the doubly linked list
class DoublyLinkedList {
private:
Node* head;
Node* tail;
int size;
public:
DoublyLinkedList() {
head = new Node(-1);
tail = new Node(-1);
head->next = tail;
tail->prev = head;
size = 0;
}
// Insert a new node at the end of the doubly linked list
void insertAtEnd(int data) {
Node* newNode = new Node(data);
Node* prevNode = tail->prev;
prevNode->next = newNode;
newNode->prev = prevNode;
newNode->next = tail;
tail->prev = newNode;
size++;
}
// Print the doubly linked list
void printList() {
Node* currentNode = head->next;
while(currentNode != tail) {
cout << currentNode->data << " ";
currentNode = currentNode->next;
}
cout << endl;
}
};
// Main function to demonstrate usage
int main() {
DoublyLinkedList list;
list.insertAtEnd(1);
list.insertAtEnd(2);
list.insertAtEnd(3);
list.insertAtEnd(4);
list.insertAtEnd(5);
list.printList(); // Output: 1 2 3 4 5
return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
// Define the doubly linked list node
typedef struct Node {
int data;
struct Node* prev;
struct Node* next;
} Node;
// Define the doubly linked list
typedef struct DoublyLinkedList {
Node* head;
Node* tail;
int size;
} DoublyLinkedList;
// Initialize the doubly linked list
void init(DoublyLinkedList* list) {
list->head = (Node*)malloc(sizeof(Node));
list->tail = (Node*)malloc(sizeof(Node));
list->head->prev = NULL;
list->head->next = list->tail;
list->tail->prev = list->head;
list->tail->next = NULL;
list->size = 0;
}
// Insert a new node at the end of the doubly linked list
void insertAtEnd(DoublyLinkedList* list, int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
Node* prevNode = list->tail->prev;
prevNode->next = newNode;
newNode->prev = prevNode;
newNode->next = list->tail;
list->tail->prev = newNode;
list->size++;
}
// Print the doubly linked list
void printList(DoublyLinkedList* list) {
Node* currentNode = list->head->next;
while(currentNode != list->tail) {
printf("%d ", currentNode->data);
currentNode = currentNode->next;
}
printf("\n");
}
// Main function to demonstrate usage
int main() {
DoublyLinkedList list;
init(&list);
insertAtEnd(&list, 1);
insertAtEnd(&list, 2);
insertAtEnd(&list, 3);
insertAtEnd(&list, 4);
insertAtEnd(&list, 5);
printList(&list); // Output: 1 2 3 4 5
return 0;
}
Java
public class DoublyLinkedList {
private Node head;
private Node tail;
private int size;
private class Node {
int data;
Node prev;
Node next;
Node(int data) {
this.data = data;
}
}
// Constructor
public DoublyLinkedList() {
head = new Node(-1); // Sentinel node for head
tail = new Node(-1); // Sentinel node for tail
head.next = tail;
tail.prev = head;
size = 0;
}
// Method to insert a new node at the end of the doubly linked list
public void insertAtEnd(int data) {
Node newNode = new Node(data);
Node prevNode = tail.prev;
prevNode.next = newNode;
newNode.prev = prevNode;
newNode.next = tail;
tail.prev = newNode;
size++;
}
// Method to print the doubly linked list
public void printList() {
Node currentNode = head.next;
while(currentNode != tail) {
System.out.print(currentNode.data + " ");
currentNode = currentNode.next;
}
System.out.println();
}
// Main method to demonstrate usage
public static void main(String[] args) {
DoublyLinkedList list = new DoublyLinkedList();
list.insertAtEnd(1);
list.insertAtEnd(2);
list.insertAtEnd(3);
list.insertAtEnd(4);
list.insertAtEnd(5);
list.printList(); // Output: 1 2 3 4 5
}
}
C#
using System;
// Define the doubly linked list node
class Node {
public int data;
public Node prev;
public Node next;
public Node(int data) {
this.data = data;
prev = null;
next = null;
}
}
// Define the doubly linked list
class DoublyLinkedList {
private Node head;
private Node tail;
private int size;
public DoublyLinkedList() {
head = new Node(-1);
tail = new Node(-1);
head.next = tail;
tail.prev = head;
size = 0;
}
// Insert a new node at the end of the doubly linked list
public void InsertAtEnd(int data) {
Node newNode = new Node(data);
Node prevNode = tail.prev;
prevNode.next = newNode;
newNode.prev = prevNode;
newNode.next = tail;
tail.prev = newNode;
size++;
}
// Print the doubly linked list
public void PrintList() {
Node currentNode = head.next;
while(currentNode != tail) {
Console.Write(currentNode.data + " ");
currentNode = currentNode.next;
}
Console.WriteLine();
}
}
// Main function to demonstrate usage
class Program {
static void Main(string[] args) {
DoublyLinkedList list = new DoublyLinkedList();
list.InsertAtEnd(1);
list.InsertAtEnd(2);
list.InsertAtEnd(3);
list.InsertAtEnd(4);
list.InsertAtEnd(5);
list.PrintList(); // Output: 1 2 3 4 5
}
}
JavaScript
// Define the doubly linked list node
class Node {
constructor(data) {
this.data = data;
this.prev = null;
this.next = null;
}
}
// Define the doubly linked list
class DoublyLinkedList {
constructor() {
this.head = new Node(-1);
this.tail = new Node(-1);
this.head.next = this.tail;
this.tail.prev = this.head;
this.size = 0;
}
// Insert a new node at the end of the doubly linked list
insertAtEnd(data) {
const newNode = new Node(data);
const prevNode = this.tail.prev;
prevNode.next = newNode;
newNode.prev = prevNode;
newNode.next = this.tail;
this.tail.prev = newNode;
this.size++;
}
// Print the doubly linked list
printList() {
let currentNode = this.head.next;
while(currentNode !== this.tail) {
process.stdout.write(currentNode.data + " ");
currentNode = currentNode.next;
}
console.log();
}
}
// Main function to demonstrate usage
function main() {
const list = new DoublyLinkedList();
list.insertAtEnd(1);
list.insertAtEnd(2);
list.insertAtEnd(3);
list.insertAtEnd(4);
list.insertAtEnd(5);
list.printList(); // Output: 1 2 3 4 5
}
main();
Python3
# Define the doubly linked list node
class Node:
def __init__(self, data):
self.data = data
self.prev = None
self.next = None
# Define the doubly linked list
class DoublyLinkedList:
def __init__(self):
self.head = Node(-1)
self.tail = Node(-1)
self.head.next = self.tail
self.tail.prev = self.head
self.size = 0
# Insert a new node at the end of the doubly linked list
def insertAtEnd(self, data):
newNode = Node(data)
prevNode = self.tail.prev
prevNode.next = newNode
newNode.prev = prevNode
newNode.next = self.tail
self.tail.prev = newNode
self.size += 1
# Print the doubly linked list
def printList(self):
currentNode = self.head.next
while currentNode != self.tail:
print(currentNode.data, end=" ")
currentNode = currentNode.next
print()
# Main function to demonstrate usage
if __name__ == '__main__':
list = DoublyLinkedList()
list.insertAtEnd(1)
list.insertAtEnd(2)
list.insertAtEnd(3)
list.insertAtEnd(4)
list.insertAtEnd(5)
list.printList() # Output: 1 2 3 4 5
2. Delete an existing node in a Doubly-Linked List using Sentinel Nodes
Deleting an existing node in a doubly-linked list can also be done in three ways. Still, as we have used the sentinel node in the doubly linked list, so we do not have to write a different algorithm for each case, we have to pass the location of the node, which we want to delete.
- Delete an existing node at the beginning of the doubly linked list
In this, we are deleting an existing node just after the head sentinel node. So basically, we are deleting an existing node at the beginning of the doubly linked list. Still, it will behave as the deletion of a node between the beginning and end node of the linked list due to the sentinel node.

Deleting the starting node in a doubly-linked list
Below is the code implementation to Delete an existing node at the beginning of the doubly linked list:
C++
#include <iostream>
struct ListNode {
int val;
ListNode *prev;
ListNode *next;
ListNode(int x) : val(x), prev(nullptr), next(nullptr) {}
};
class DoublyLinkedList {
private:
ListNode *head;
ListNode *tail;
public:
DoublyLinkedList() {
head = new ListNode(-1);
tail = new ListNode(-1);
head->next = tail;
tail->prev = head;
}
void insertFirstNode(int val) {
ListNode *newNode = new ListNode(val);
newNode->prev = head;
newNode->next = head->next;
head->next->prev = newNode;
head->next = newNode;
}
void deleteFirstNode() {
if (head->next == tail) {
std::cout << "List is empty." << std::endl;
return;
}
ListNode *firstNode = head->next;
head->next = firstNode->next;
firstNode->next->prev = head;
delete firstNode;
}
void printList() {
ListNode *curr = head->next;
while (curr != tail) {
std::cout << curr->val << " ";
curr = curr->next;
}
std::cout << std::endl;
}
};
int main() {
DoublyLinkedList list;
list.insertFirstNode(3);
list.insertFirstNode(2);
list.insertFirstNode(1);
std::cout << "Before deletion: ";
list.printList();
list.deleteFirstNode();
std::cout << "After deletion: ";
list.printList();
return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int val;
struct ListNode *prev;
struct ListNode *next;
};
struct DoublyLinkedList {
struct ListNode *head;
struct ListNode *tail;
};
void insertFirstNode(struct DoublyLinkedList *list, int val) {
struct ListNode *newNode = (struct ListNode*) malloc(sizeof(struct ListNode));
newNode->val = val;
newNode->prev = NULL;
newNode->next = list->head->next;
if (list->head->next != NULL) {
list->head->next->prev = newNode;
} else {
list->tail = newNode;
}
list->head->next = newNode;
}
void deleteFirstNode(struct DoublyLinkedList *list) {
if (list->head->next == NULL) {
printf("List is empty.\n");
return;
}
struct ListNode *firstNode = list->head->next;
list->head->next = firstNode->next;
if (firstNode->next != NULL) {
firstNode->next->prev = list->head;
} else {
list->tail = list->head;
}
free(firstNode);
}
int main() {
struct DoublyLinkedList list;
list.head = (struct ListNode*) malloc(sizeof(struct ListNode));
list.tail = (struct ListNode*) malloc(sizeof(struct ListNode));
list.head->val = -1;
list.head->prev = NULL;
list.head->next = list.tail;
list.tail->val = -1;
list.tail->prev = list.head;
list.tail->next = NULL;
insertFirstNode(&list, 3);
insertFirstNode(&list, 2);
insertFirstNode(&list, 1);
printf("Before deletion: ");
struct ListNode *curr = list.head->next;
while (curr != list.tail) {
printf("%d ", curr->val);
curr = curr->next;
}
printf("\n");
deleteFirstNode(&list);
printf("After deletion: ");
curr = list.head->next;
while (curr != list.tail) {
printf("%d ", curr->val);
curr = curr->next;
}
printf("\n");
return 0;
}
Java
class ListNode {
int val;
ListNode prev;
ListNode next;
public ListNode(int val) {
this.val = val;
this.prev = null;
this.next = null;
}
}
class DoublyLinkedList {
ListNode head;
ListNode tail;
public DoublyLinkedList() {
head = new ListNode(-1);
tail = new ListNode(-1);
head.next = tail;
tail.prev = head;
}
public void insertFirstNode(int val) {
ListNode newNode = new ListNode(val);
newNode.next = head.next;
head.next.prev = newNode;
head.next = newNode;
newNode.prev = head;
}
public void deleteFirstNode() {
if (head.next == tail) {
System.out.println("List is empty.");
return;
}
ListNode firstNode = head.next;
head.next = firstNode.next;
firstNode.next.prev = head;
firstNode.prev = null;
firstNode.next = null;
System.out.println("Deleted node with value " + firstNode.val);
}
}
public class Main {
public static void main(String[] args) {
DoublyLinkedList list = new DoublyLinkedList();
list.insertFirstNode(3);
list.insertFirstNode(2);
list.insertFirstNode(1);
System.out.println("Before deletion:");
printList(list);
list.deleteFirstNode();
System.out.println("After deletion:");
printList(list);
}
public static void printList(DoublyLinkedList list) {
ListNode curr = list.head.next;
while (curr != list.tail) {
System.out.print(curr.val + " ");
curr = curr.next;
}
System.out.println();
}
}
C#
using System;
public class ListNode
{
public int val;
public ListNode prev;
public ListNode next;
public ListNode(int val = 0, ListNode prev = null, ListNode next = null)
{
this.val = val;
this.prev = prev;
this.next = next;
}
}
public class DoublyLinkedList
{
private ListNode head;
private ListNode tail;
public DoublyLinkedList()
{
head = new ListNode();
tail = new ListNode();
head.next = tail;
tail.prev = head;
}
public void InsertFirstNode(int val)
{
ListNode new_node = new ListNode(val, head, head.next);
head.next.prev = new_node;
head.next = new_node;
}
public void DeleteFirstNode()
{
if (head.next == tail)
{
Console.WriteLine("List is empty.");
return;
}
ListNode first_node = head.next;
head.next = first_node.next;
first_node.next.prev = head;
first_node = null;
}
public void PrintList()
{
ListNode curr = head.next;
while (curr != tail)
{
Console.Write(curr.val + " ");
curr = curr.next;
}
Console.WriteLine();
}
}
public class Program
{
public static void Main()
{
DoublyLinkedList linked_list = new DoublyLinkedList();
linked_list.InsertFirstNode(3);
linked_list.InsertFirstNode(2);
linked_list.InsertFirstNode(1);
Console.Write("Before deletion: ");
linked_list.PrintList();
linked_list.DeleteFirstNode();
Console.Write("After deletion: ");
linked_list.PrintList();
}
}
JavaScript
class ListNode {
constructor(val = 0, prev = null, next = null) {
this.val = val;
this.prev = prev;
this.next = next;
}
}
class DoublyLinkedList {
constructor() {
this.head = new ListNode();
this.tail = new ListNode();
this.head.next = this.tail;
this.tail.prev = this.head;
}
insertFirstNode(val) {
const new_node = new ListNode(val, this.head, this.head.next);
this.head.next.prev = new_node;
this.head.next = new_node;
}
deleteFirstNode() {
if (this.head.next === this.tail) {
console.log("List is empty.");
return;
}
let first_node = this.head.next;
this.head.next = first_node.next;
first_node.next.prev = this.head;
first_node = null;
}
printList() {
let curr = this.head.next;
while (curr !== this.tail) {
console.log(curr.val);
curr = curr.next;
}
}
}
const linked_list = new DoublyLinkedList();
linked_list.insertFirstNode(3);
linked_list.insertFirstNode(2);
linked_list.insertFirstNode(1);
console.log("Before deletion:");
linked_list.printList();
linked_list.deleteFirstNode();
console.log("After deletion:");
linked_list.printList();
PHP
class ListNode {
public $val;
public $prev;
public $next;
public function __construct($val = 0, $prev = null, $next = null) {
$this->val = $val;
$this->prev = $prev;
$this->next = $next;
}
}
class DoublyLinkedList {
public $head;
public $tail;
public function __construct() {
$this->head = new ListNode();
$this->tail = new ListNode();
$this->head->next = $this->tail;
$this->tail->prev = $this->head;
}
public function insertFirstNode($val) {
$new_node = new ListNode($val, $this->head, $this->head->next);
$this->head->next->prev = $new_node;
$this->head->next = $new_node;
}
public function deleteFirstNode() {
if ($this->head->next === $this->tail) {
echo "List is empty.\n";
return;
}
$first_node = $this->head->next;
$this->head->next = $first_node->next;
$first_node->next->prev = $this->head;
$first_node = null;
}
public function printList() {
$curr = $this->head->next;
while ($curr !== $this->tail) {
echo $curr->val . "\n";
$curr = $curr->next;
}
}
}
$linked_list = new DoublyLinkedList();
$linked_list->insertFirstNode(3);
$linked_list->insertFirstNode(2);
$linked_list->insertFirstNode(1);
echo "Before deletion:\n";
$linked_list->printList();
$linked_list->deleteFirstNode();
echo "After deletion:\n";
$linked_list->printList();
Python3
class ListNode:
def __init__(self, val=0, prev=None, next=None):
self.val = val
self.prev = prev
self.next = next
class DoublyLinkedList:
def __init__(self):
self.head = ListNode()
self.tail = ListNode()
self.head.next = self.tail
self.tail.prev = self.head
def insertFirstNode(self, val: int) -> None:
new_node = ListNode(val, self.head, self.head.next)
self.head.next.prev = new_node
self.head.next = new_node
def deleteFirstNode(self) -> None:
if self.head.next == self.tail:
print("List is empty.")
return
first_node = self.head.next
self.head.next = first_node.next
first_node.next.prev = self.head
del first_node
def printList(self) -> None:
curr = self.head.next
while curr != self.tail:
print(curr.val, end=" ")
curr = curr.next
print()
if __name__ == "__main__":
linked_list = DoublyLinkedList()
linked_list.insertFirstNode(3)
linked_list.insertFirstNode(2)
linked_list.insertFirstNode(1)
print("Before deletion: ", end="")
linked_list.printList()
linked_list.deleteFirstNode()
print("After deletion: ", end="")
linked_list.printList()
- Delete an existing node at a given position in the linked list
As shown in the diagram given below, we are deleting an existing node at a given location of the linked list.

Deleting node at a given position in the doubly linked list
Below is the code implementation to Delete an existing node at a given position in the linked list:
C++
#include <iostream>
using namespace std;
class Node {
public:
int val;
Node* next;
Node(int val) {
this->val = val;
this->next = nullptr;
}
};
class LinkedList {
private:
Node* sentinel;
int size;
public:
LinkedList() {
sentinel = new Node(-1);
sentinel->next = sentinel;
size = 0;
}
void insert(int val) {
Node* node = new Node(val);
node->next = sentinel;
Node* prev = sentinel;
while (prev->next != sentinel) {
prev = prev->next;
}
prev->next = node;
size++;
}
void deleteNode(int position) {
if (position < 0 || position >= size) {
throw "Invalid position";
}
Node* prev = sentinel;
for (int i = 0; i < position; i++) {
prev = prev->next;
}
Node* curr = prev->next;
prev->next = curr->next;
curr->next = nullptr;
delete curr;
size--;
}
void printList() {
Node* curr = sentinel->next;
while (curr != sentinel) {
cout << curr->val << " ";
curr = curr->next;
}
cout << endl;
}
};
int main() {
LinkedList list;
list.insert(1);
list.insert(2);
list.insert(3);
cout << "Before deletion:" << endl;
list.printList();
list.deleteNode(1);
cout << "After deletion:" << endl;
list.printList();
return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
// Define the Node structure
struct Node {
int val;
struct Node* next;
};
// Define the LinkedList structure
struct LinkedList {
struct Node* sentinel;
int size;
};
// Constructor to initialize the sentinel node
struct LinkedList* newLinkedList() {
struct LinkedList* list = (struct LinkedList*) malloc(sizeof(struct LinkedList));
list->sentinel = (struct Node*) malloc(sizeof(struct Node));
list->sentinel->val = -1;
list->sentinel->next = list->sentinel;
list->size = 0;
return list;
}
// Method to insert a node at the end of the list
void insert(struct LinkedList* list, int val) {
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
node->val = val;
node->next = list->sentinel;
struct Node* prev = list->sentinel;
while (prev->next != list->sentinel) {
prev = prev->next;
}
prev->next = node;
list->size++;
}
// Method to delete a node at the given position
void delete(struct LinkedList* list, int position) {
if (position < 0 || position >= list->size) {
printf("Invalid position\n");
return;
}
struct Node* prev = list->sentinel;
for (int i = 0; i < position; i++) {
prev = prev->next;
}
struct Node* curr = prev->next;
prev->next = curr->next;
curr->next = NULL;
free(curr);
list->size--;
}
// Method to print the list
void printList(struct LinkedList* list) {
struct Node* curr = list->sentinel->next;
while (curr != list->sentinel) {
printf("%d ", curr->val);
curr = curr->next;
}
printf("\n");
}
int main() {
struct LinkedList* list = newLinkedList();
insert(list, 1);
insert(list, 2);
insert(list, 3);
printf("Before deletion:\n");
printList(list);
delete(list, 1);
printf("After deletion:\n");
printList(list);
return 0;
}
Java
public class LinkedList {
private Node sentinel;
private int size;
// Constructor to initialize the sentinel node
public LinkedList() {
sentinel = new Node(-1);
sentinel.next = sentinel;
size = 0;
}
// Method to insert a node at the end of the list
public void insert(int val) {
Node node = new Node(val);
node.next = sentinel;
Node prev = sentinel;
while (prev.next != sentinel) {
prev = prev.next;
}
prev.next = node;
size++;
}
// Method to delete a node at the given position
public void delete(int position) {
if (position < 0 || position >= size) {
throw new IndexOutOfBoundsException("Invalid position");
}
Node prev = sentinel;
for (int i = 0; i < position; i++) {
prev = prev.next;
}
Node curr = prev.next;
prev.next = curr.next;
curr.next = null;
size--;
}
// Method to print the list
public void printList() {
Node curr = sentinel.next;
while (curr != sentinel) {
System.out.print(curr.val + " ");
curr = curr.next;
}
System.out.println();
}
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.insert(1);
list.insert(2);
list.insert(3);
System.out.println("Before deletion:");
list.printList();
list.delete(1);
System.out.println("After deletion:");
list.printList();
}
}
class Node {
int val;
Node next;
public Node(int val) {
this.val = val;
this.next = null;
}
}
C#
using System;
public class LinkedList {
private Node sentinel;
private int size;
// Constructor to initialize the sentinel node
public LinkedList() {
sentinel = new Node(-1);
sentinel.next = sentinel;
size = 0;
}
// Method to insert a node at the end of the list
public void insert(int val) {
Node node = new Node(val);
node.next = sentinel;
Node prev = sentinel;
while (prev.next != sentinel) {
prev = prev.next;
}
prev.next = node;
size++;
}
// Method to delete a node at the given position
public void delete(int position) {
if (position < 0 || position >= size) {
throw new IndexOutOfRangeException("Invalid position");
}
Node prev = sentinel;
for (int i = 0; i < position; i++) {
prev = prev.next;
}
Node curr = prev.next;
prev.next = curr.next;
curr.next = null;
size--;
}
// Method to print the list
public void printList() {
Node curr = sentinel.next;
while (curr != sentinel) {
Console.Write(curr.val + " ");
curr = curr.next;
}
Console.WriteLine();
}
public static void Main() {
LinkedList list = new LinkedList();
list.insert(1);
list.insert(2);
list.insert(3);
Console.WriteLine("Before deletion:");
list.printList();
list.delete(1);
Console.WriteLine("After deletion:");
list.printList();
}
}
public class Node {
public int val;
public Node next;
public Node(int val) {
this.val = val;
this.next = null;
}
}
JavaScript
class Node {
constructor(val) {
this.val = val;
this.next = null;
}
}
class LinkedList {
constructor() {
this.sentinel = new Node(-1);
this.sentinel.next = this.sentinel;
this.size = 0;
}
insert(val) {
const node = new Node(val);
node.next = this.sentinel;
let prev = this.sentinel;
while (prev.next !== this.sentinel) {
prev = prev.next;
}
prev.next = node;
this.size++;
}
delete(position) {
if (position < 0 || position >= this.size) {
throw new Error("Invalid position");
}
let prev = this.sentinel;
for (let i = 0; i < position; i++) {
prev = prev.next;
}
let curr = prev.next;
prev.next = curr.next;
curr.next = null;
this.size--;
}
printList() {
let curr = this.sentinel.next;
while (curr !== this.sentinel) {
console.log(curr.val + " ");
curr = curr.next;
}
console.log();
}
}
// Sample usage
const list = new LinkedList();
list.insert(1);
list.insert(2);
list.insert(3);
console.log("Before deletion:");
list.printList();
list.delete(1);
console.log("After deletion:");
list.printList();
PHP
<?php
class Node {
public $val;
public $next;
public function __construct($val) {
$this->val = $val;
$this->next = null;
}
}
class LinkedList {
private $sentinel;
private $size;
public function __construct() {
$this->sentinel = new Node(-1);
$this->sentinel->next = $this->sentinel;
$this->size = 0;
}
public function insert($val) {
$node = new Node($val);
$node->next = $this->sentinel;
$prev = $this->sentinel;
while ($prev->next !== $this->sentinel) {
$prev = $prev->next;
}
$prev->next = $node;
$this->size++;
}
public function delete($position) {
if ($position < 0 || $position >= $this->size) {
throw new Exception("Invalid position");
}
$prev = $this->sentinel;
for ($i = 0; $i < $position; $i++) {
$prev = $prev->next;
}
$curr = $prev->next;
$prev->next = $curr->next;
$curr->next = null;
$this->size--;
}
public function printList() {
$curr = $this->sentinel->next;
while ($curr !== $this->sentinel) {
echo $curr->val . " ";
$curr = $curr->next;
}
echo "\n";
}
}
$list = new LinkedList();
$list->insert(1);
$list->insert(2);
$list->insert(3);
echo "Before deletion: ";
$list->printList();
$list->delete(1);
echo "After deletion: ";
$list->printList();
?>
Python3
class Node:
def __init__(self, val):
self.val = val
self.next = None
class LinkedList:
def __init__(self):
self.sentinel = Node(-1)
self.sentinel.next = self.sentinel
self.size = 0
def insert(self, val):
node = Node(val)
node.next = self.sentinel
prev = self.sentinel
while prev.next != self.sentinel:
prev = prev.next
prev.next = node
self.size += 1
def delete(self, position):
if position < 0 or position >= self.size:
raise IndexError("Invalid position")
prev = self.sentinel
for i in range(position):
prev = prev.next
curr = prev.next
prev.next = curr.next
curr.next = None
self.size -= 1
def printList(self):
curr = self.sentinel.next
while curr != self.sentinel:
print(curr.val, end=' ')
curr = curr.next
print()
# sample usage
list = LinkedList()
list.insert(1)
list.insert(2)
list.insert(3)
print("Before deletion:")
list.printList()
list.delete(1)
print("After deletion:")
list.printList()
- Delete an existing node at the end of the doubly linked list
In this, we are deleting an existing node just before the tail sentinel node. So basically, we are deleting an existing node at the end of the doubly linked list. Still, it will behave as the deletion of a node between the beginning and end node of the linked list due to the sentinel node.

Deleting the ending node in the doubly linked list
Below is the code implementation to Delete an existing node at the end of the doubly linked list:
C++
#include <iostream>
#include <stdexcept>
using namespace std;
class Node {
public:
int val;
Node* next;
Node* prev;
Node(int val) {
this->val = val;
this->next = nullptr;
this->prev = nullptr;
}
};
class DoublyLinkedList {
private:
Node* sentinel;
int size;
public:
DoublyLinkedList() {
sentinel = new Node(-1);
sentinel->next = sentinel;
sentinel->prev = sentinel;
size = 0;
}
void insert(int val) {
Node* node = new Node(val);
node->next = sentinel;
node->prev = sentinel->prev;
sentinel->prev->next = node;
sentinel->prev = node;
size++;
}
void deleteLast() {
if (size == 0) {
throw runtime_error("List is empty");
}
Node* lastNode = sentinel->prev;
lastNode->prev->next = sentinel;
sentinel->prev = lastNode->prev;
lastNode->prev = nullptr;
lastNode->next = nullptr;
delete lastNode;
size--;
}
void printList() {
Node* curr = sentinel->next;
while (curr != sentinel) {
cout << curr->val << " ";
curr = curr->next;
}
cout << endl;
}
~DoublyLinkedList() {
while (sentinel->next != sentinel) {
deleteLast();
}
delete sentinel;
}
};
int main() {
DoublyLinkedList list;
list.insert(1);
list.insert(2);
list.insert(3);
cout << "Before deletion:" << endl;
list.printList();
list.deleteLast();
cout << "After deletion:" << endl;
list.printList();
return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int val;
struct Node* next;
struct Node* prev;
} Node;
typedef struct DoublyLinkedList {
Node* sentinel;
int size;
} DoublyLinkedList;
void initList(DoublyLinkedList* list) {
list->sentinel = malloc(sizeof(Node));
list->sentinel->val = -1;
list->sentinel->next = list->sentinel;
list->sentinel->prev = list->sentinel;
list->size = 0;
}
void insert(DoublyLinkedList* list, int val) {
Node* node = malloc(sizeof(Node));
node->val = val;
node->next = list->sentinel;
node->prev = list->sentinel->prev;
list->sentinel->prev->next = node;
list->sentinel->prev = node;
list->size++;
}
void deleteLast(DoublyLinkedList* list) {
if (list->size == 0) {
fprintf(stderr, "List is empty\n");
exit(1);
}
Node* lastNode = list->sentinel->prev;
lastNode->prev->next = list->sentinel;
list->sentinel->prev = lastNode->prev;
lastNode->prev = NULL;
lastNode->next = NULL;
free(lastNode);
list->size--;
}
void printList(DoublyLinkedList* list) {
Node* curr = list->sentinel->next;
while (curr != list->sentinel) {
printf("%d ", curr->val);
curr = curr->next;
}
printf("\n");
}
int main() {
DoublyLinkedList list;
initList(&list);
insert(&list, 1);
insert(&list, 2);
insert(&list, 3);
printf("Before deletion:\n");
printList(&list);
deleteLast(&list);
printf("After deletion:\n");
printList(&list);
return 0;
}
Java
import java.util.NoSuchElementException;
public class DoublyLinkedList {
private Node sentinel;
private int size;
public DoublyLinkedList() {
sentinel = new Node(-1);
sentinel.next = sentinel;
sentinel.prev = sentinel;
size = 0;
}
public void insert(int val) {
Node node = new Node(val);
node.next = sentinel;
node.prev = sentinel.prev;
sentinel.prev.next = node;
sentinel.prev = node;
size++;
}
public void deleteLast() {
if (size == 0) {
throw new NoSuchElementException("List is empty");
}
Node lastNode = sentinel.prev;
lastNode.prev.next = sentinel;
sentinel.prev = lastNode.prev;
lastNode.prev = null;
lastNode.next = null;
size--;
}
public void printList() {
Node curr = sentinel.next;
while (curr != sentinel) {
System.out.print(curr.val + " ");
curr = curr.next;
}
System.out.println();
}
public static void main(String[] args) {
DoublyLinkedList list = new DoublyLinkedList();
list.insert(1);
list.insert(2);
list.insert(3);
System.out.println("Before deletion:");
list.printList();
list.deleteLast();
System.out.println("After deletion:");
list.printList();
}
}
class Node {
int val;
Node next;
Node prev;
public Node(int val) {
this.val = val;
this.next = null;
this.prev = null;
}
}
C#
using System;
class Node {
public int val;
public Node next;
public Node prev;
public Node(int val) {
this.val = val;
this.next = null;
this.prev = null;
}
}
class DoublyLinkedList {
private Node sentinel;
private int size;
public DoublyLinkedList() {
sentinel = new Node(-1);
sentinel.next = sentinel;
sentinel.prev = sentinel;
size = 0;
}
public void insert(int val) {
Node node = new Node(val);
node.next = sentinel;
node.prev = sentinel.prev;
sentinel.prev.next = node;
sentinel.prev = node;
size++;
}
public void deleteLast() {
if (size == 0) {
throw new InvalidOperationException("List is empty");
}
Node lastNode = sentinel.prev;
lastNode.prev.next = sentinel;
sentinel.prev = lastNode.prev;
lastNode.prev = null;
lastNode.next = null;
size--;
}
public void printList() {
Node curr = sentinel.next;
while (curr != sentinel) {
Console.Write(curr.val + " ");
curr = curr.next;
}
Console.WriteLine();
}
public static void Main() {
DoublyLinkedList list = new DoublyLinkedList();
list.insert(1);
list.insert(2);
list.insert(3);
Console.WriteLine("Before deletion:");
list.printList();
list.deleteLast();
Console.WriteLine("After deletion:");
list.printList();
}
}
JavaScript
class Node {
constructor(val) {
this.val = val;
this.next = null;
this.prev = null;
}
}
class DoublyLinkedList {
constructor() {
this.sentinel = new Node(-1);
this.sentinel.next = this.sentinel;
this.sentinel.prev = this.sentinel;
this.size = 0;
}
insert(val) {
const node = new Node(val);
node.next = this.sentinel;
node.prev = this.sentinel.prev;
this.sentinel.prev.next = node;
this.sentinel.prev = node;
this.size++;
}
deleteLast() {
if (this.size === 0) {
throw new Error("List is empty");
}
const lastNode = this.sentinel.prev;
lastNode.prev.next = this.sentinel;
this.sentinel.prev = lastNode.prev;
lastNode.prev = null;
lastNode.next = null;
this.size--;
}
printList() {
let curr = this.sentinel.next;
while (curr !== this.sentinel) {
console.log(curr.val + " ");
curr = curr.next;
}
console.log();
}
}
const list = new DoublyLinkedList();
list.insert(1);
list.insert(2);
list.insert(3);
console.log("Before deletion:");
list.printList();
list.deleteLast();
console.log("After deletion:");
list.printList();
PHP
<?php
class Node {
public $val;
public $next;
public $prev;
public function __construct($val) {
$this->val = $val;
$this->next = null;
$this->prev = null;
}
}
class DoublyLinkedList {
private $sentinel;
private $size;
public function __construct() {
$this->sentinel = new Node(-1);
$this->sentinel->next = $this->sentinel;
$this->sentinel->prev = $this->sentinel;
$this->size = 0;
}
public function insert($val) {
$node = new Node($val);
$node->next = $this->sentinel;
$node->prev = $this->sentinel->prev;
$this->sentinel->prev->next = $node;
$this->sentinel->prev = $node;
$this->size++;
}
public function deleteLast() {
if ($this->size == 0) {
throw new Exception("List is empty");
}
$lastNode = $this->sentinel->prev;
$lastNode->prev->next = $this->sentinel;
$this->sentinel->prev = $lastNode->prev;
$lastNode->prev = null;
$lastNode->next = null;
$this->size--;
}
public function printList() {
$curr = $this->sentinel->next;
while ($curr != $this->sentinel) {
echo $curr->val . " ";
$curr = $curr->next;
}
echo "\n";
}
}
$list = new DoublyLinkedList();
$list->insert(1);
$list->insert(2);
$list->insert(3);
echo "Before deletion:\n";
$list->printList();
$list->deleteLast();
echo "After deletion:\n";
$list->printList();
?>
Python3
class Node:
def __init__(self, val):
self.val = val
self.next = None
self.prev = None
class DoublyLinkedList:
def __init__(self):
self.sentinel = Node(-1)
self.sentinel.next = self.sentinel
self.sentinel.prev = self.sentinel
self.size = 0
def insert(self, val):
node = Node(val)
node.next = self.sentinel
node.prev = self.sentinel.prev
self.sentinel.prev.next = node
self.sentinel.prev = node
self.size += 1
def deleteLast(self):
if self.size == 0:
raise ValueError("List is empty")
lastNode = self.sentinel.prev
lastNode.prev.next = self.sentinel
self.sentinel.prev = lastNode.prev
lastNode.prev = None
lastNode.next = None
self.size -= 1
def printList(self):
curr = self.sentinel.next
while curr != self.sentinel:
print(curr.val, end=" ")
curr = curr.next
print()
def __del__(self):
while self.sentinel.next != self.sentinel:
self.deleteLast()
del self.sentinel
# Example usage
list = DoublyLinkedList()
list.insert(1)
list.insert(2)
list.insert(3)
print("Before deletion:")
list.printList()
list.deleteLast()
print("After deletion:")
list.printList()
3. Display all the nodes’ data in a Doubly-Linked List using Sentinel Nodes
It is the same as the simple doubly linked list. We have to travel through all the nodes and print the data stored in them except the sentinel nodes.
Implementation: The full implementation of the doubly linked list with sentinel nodes and insertion, deletion, and display operation is shown below.
C++
// C++ code to implement doubly-linked list
// using sentinel node
#include <bits/stdc++.h>
using namespace std;
int size = 0;
// Each node contains the data,
// previous node pointer and
// the next node pointer
struct node {
int data;
struct node* next;
struct node* pre;
};
// To create a node, first define the node pointer
// and than assign the memory required by node
// and return the pointer
struct node* createnode()
{
struct node* t;
t = (struct node*)malloc(sizeof(struct node));
return (t);
}
// Function to display all the nodes
void display(struct node* head,
struct node* tail)
{
head = head->next;
cout << "\nThe linked list is :- ";
while (head != tail) {
cout << head->data << " ";
head = head->next;
}
}
// Function to insert a new node
void insertion(struct node* head,
struct node* tail,
int n, int value)
{
n--;
struct node *temp, *ptr;
ptr = head;
temp = createnode();
temp->data = value;
int i = 0;
// Run's until reach the node after
// which we have to add the new node
while (i < n) {
ptr = ptr->next;
i++;
}
temp->next = ptr->next;
temp->pre = ptr;
ptr->next = temp;
(temp->next)->pre = temp;
// Linked list size is increased by 1
size++;
}
// Function to delete an element
// from the doubly-linked list
void deletion(struct node* head,
struct node* tail, int n)
{
n--;
// If linked list is empty
if (head->next == tail) {
cout << "\nerror : linked list is empty";
return;
}
// If entered position is more
// than the size of the linked list
if (n >= size) {
cout << "\nerror : position is larger"
" than size of linked list";
return;
}
struct node* ptr = head;
struct node* temp;
int i = 0;
// Run's until reach the node whose
// next node have to deleted
while (i < n) {
ptr = ptr->next;
i++;
}
cout << "\nDeleting node at position "
<< n + 1 << " contains value "
<< (ptr->next)->data;
temp = (ptr->next)->next;
ptr->next = temp;
temp->pre = ptr;
// Size of the linked list decreased by 1
size--;
}
// Driver code
int main()
{
// Here we are creating two sentinel nodes
// (does not contain any data)
struct node* head = createnode();
head->pre = NULL;
struct node* tail = createnode();
tail->pre = head;
tail->next = NULL;
head->next = tail;
int n;
// Declaring start position of goto section
start:
cout << "\n1. Insertion\n2. Deletion\n"
"3. Display\n0. Exit\n";
cin >> n;
switch (n) {
case 1:
// Insertion at the beginning
// of the Doubly linked list
insertion(head, tail, 1, 10);
display(head, tail);
// Insertion at the End
// of the Doubly linked list
insertion(head, tail, size + 1, 14);
display(head, tail);
// Inserting node in between
// the doubly linked list
insertion(head, tail, 2, 8);
display(head, tail);
cout << endl;
goto start;
break;
case 2:
// Deleting the node at location 2
deletion(head, tail,
2);
display(head, tail);
cout << endl;
// Deleting the first node
deletion(head, tail, 1);
display(head, tail);
cout << endl;
// Deleting the last node
deletion(head, tail, size);
display(head, tail);
cout << endl;
goto start;
case 3:
display(head, tail);
cout << endl;
goto start;
default:
break;
}
return 0;
}
Java
import java.util.Scanner;
public class DoublyLinkedList {
static int size = 0;
// Each node contains the data,
// previous node pointer and
// the next node pointer
static class Node {
int data;
Node next;
Node pre;
Node(int data) {
this.data = data;
next = null;
pre = null;
}
}
// Function to display all the nodes
static void display(Node head, Node tail) {
head = head.next;
System.out.print("\nThe linked list is :- ");
while (head != tail) {
System.out.print(head.data + " ");
head = head.next;
}
}
// Function to insert a new node
static void insertion(Node head, Node tail, int n, int value) {
n--;
Node temp = new Node(value);
Node ptr = head;
int i = 0;
// Run's until reach the node after
// which we have to add the new node
while (i < n) {
ptr = ptr.next;
i++;
}
temp.next = ptr.next;
temp.pre = ptr;
ptr.next = temp;
(temp.next).pre = temp;
// Linked list size is increased by 1
size++;
}
// Function to delete an element
// from the doubly-linked list
static void deletion(Node head, Node tail, int n) {
n--;
// If linked list is empty
if (head.next == tail) {
System.out.println("\nerror : linked list is empty");
return;
}
// If entered position is more
// than the size of the linked list
if (n >= size) {
System.out.println("\nerror : position is larger than size of linked list");
return;
}
Node ptr = head;
Node temp;
int i = 0;
// Run's until reach the node whose
// next node have to deleted
while (i < n) {
ptr = ptr.next;
i++;
}
System.out.println("\nDeleting node at position " + (n + 1) + " contains value " + ptr.next.data);
temp = ptr.next.next;
ptr.next = temp;
temp.pre = ptr;
// Size of the linked list decreased by 1
size--;
}
// Driver code
public static void main(String[] args) {
// Here we are creating two sentinel nodes
// (does not contain any data)
Node head = new Node(0);
head.pre = null;
Node tail = new Node(0);
tail.pre = head;
tail.next = null;
head.next = tail;
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("\n1. Insertion\n2. Deletion\n3. Display\n0. Exit\n");
int choice = scanner.nextInt();
switch (choice) {
case 1:
// Insertion at the beginning
// of the Doubly linked list
insertion(head, tail, 1, 10);
display(head, tail);
// Insertion at the End
// of the Doubly linked list
insertion(head, tail, size + 1, 14);
display(head, tail);
// Inserting node in between
// the doubly linked list
insertion(head, tail, 2, 8);
display(head, tail);
System.out.println();
break;
case 2:
// Deleting the node at location 2
deletion(head, tail, 2);
display(head, tail);
// Deleting the first node
deletion(head, tail, 1);
display(head, tail);
// Deleting the last node
deletion(head, tail, size);
display(head, tail);
break;
case 3:
display(head, tail);
break;
case 0:
scanner.close();
System.exit(0);
default:
System.out.println("Invalid choice!");
}
}
}
}
C#
using System;
public class Node
{
public int data; // Data stored in the node
public Node next; // Reference to the next node in the list
public Node pre; // Reference to the previous node in the list
// Constructor to initialize the node with data
public Node(int data)
{
this.data = data;
this.next = null;
this.pre = null;
}
}
public class DoublyLinkedList
{
static int[] size = new int[1]; // Array to store the size of the linked list
// Function to display all the nodes in the linked list
static void Display(Node head, Node tail)
{
Node current = head.next;
Console.Write("\nThe linked list is :- ");
while (current != tail)
{
Console.Write(current.data + " ");
current = current.next;
}
}
// Function to insert a new node at a specified position in the linked list
static void Insertion(Node head, Node tail, int n, int value)
{
n--; // Decrement n to match array indexing
Node temp = new Node(value); // Create a new node with the given value
Node ptr = head; // Pointer to traverse the list
int i = 0;
// Traverse the list to reach the node before the insertion point
while (i < n)
{
ptr = ptr.next;
i++;
}
// Perform the insertion
temp.next = ptr.next;
temp.pre = ptr;
ptr.next = temp;
temp.next.pre = temp;
// Increase the size of the linked list
size[0]++;
}
// Function to delete a node at a specified position from the linked list
static void Deletion(Node head, Node tail, int n)
{
n--; // Decrement n to match array indexing
// Check if the list is empty
if (head.next == tail)
{
Console.WriteLine("\nerror : linked list is empty");
return;
}
// Check if the position is valid
if (n >= size[0])
{
Console.WriteLine("\nerror : position is larger than size of linked list");
return;
}
Node ptr = head; // Pointer to traverse the list
Node temp = null; // Temporary node for deletion
int i = 0;
// Traverse the list to reach the node before the deletion point
while (i < n)
{
ptr = ptr.next;
i++;
}
// Perform the deletion
Console.WriteLine($"\nDeleting node at position {n + 1} contains value {ptr.next.data}");
temp = ptr.next.next;
ptr.next = temp;
temp.pre = ptr;
// Decrease the size of the linked list
size[0]--;
}
// Function to get user input for menu selection
static int GetUserChoice()
{
string input = Console.ReadLine(); // Read user input
if (input == null)
return 0; // Return 0 to exit the loop
try
{
return int.Parse(input); // Parse the input to integer
}
catch (FormatException)
{
return 0; // Return 0 to exit the loop if input is not valid
}
}
// Main method to demonstrate the doubly linked list operations
public static void Main(string[] args)
{
Node head = new Node(0); // Create a sentinel node for the head
head.pre = null;
Node tail = new Node(0); // Create a sentinel node for the tail
tail.pre = head;
tail.next = null;
head.next = tail;
size[0] = 0; // Initialize the size of the linked list
// Loop to display menu and perform operations until the user chooses to exit
while (true)
{
Console.WriteLine("\n1. Insertion\n2. Deletion\n3. Display\n0. Exit");
// Prompt for user input with a default choice of 0 to exit
int n = GetUserChoice();
// Perform operations based on user input
if (n == 1)
{
// Insertion at the beginning
Insertion(head, tail, 1, 10);
Display(head, tail);
// Insertion at the End
Insertion(head, tail, size[0] + 1, 14);
Display(head, tail);
// Inserting node in between
Insertion(head, tail, 2, 8);
Display(head, tail);
}
else if (n == 2)
{
// Deleting the node at location 2
Deletion(head, tail, 2);
Display(head, tail);
// Deleting the first node
Deletion(head, tail, 1);
Display(head, tail);
// Deleting the last node
Deletion(head, tail, size[0]);
Display(head, tail);
}
else if (n == 3)
{
Display(head, tail);
}
else
{
break; // Exit the loop if the user chooses to exit
}
}
}
}
//This code is contributed by Kishan.
JavaScript
let size = 0;
// Each node contains the data,
// previous node pointer, and
// the next node pointer
class Node {
constructor(data) {
this.data = data;
this.next = null;
this.pre = null;
}
}
// Function to display all the nodes
function display(head, tail) {
let current = head.next;
let result = "\nThe linked list is :- ";
while (current !== tail) {
result += current.data + " ";
current = current.next;
}
console.log(result);
}
// Function to insert a new node
function insertion(head, tail, n, value) {
n--;
let ptr = head;
const temp = new Node(value);
let i = 0;
// Run until reach the node after
// which we have to add the new node
while (i < n) {
ptr = ptr.next;
i++;
}
temp.next = ptr.next;
temp.pre = ptr;
ptr.next = temp;
temp.next.pre = temp;
// Linked list size is increased by 1
size++;
}
// Function to delete an element
// from the doubly-linked list
function deletion(head, tail, n) {
n--;
// If linked list is empty
if (head.next === tail) {
console.log("\nerror : linked list is empty");
return;
}
// If entered position is more
// than the size of the linked list
if (n >= size) {
console.log("\nerror : position is larger than size of linked list");
return;
}
let ptr = head;
let i = 0;
// Run until reach the node whose
// next node have to be deleted
while (i < n) {
ptr = ptr.next;
i++;
}
console.log("\nDeleting node at position " + (n + 1) + " contains value " + ptr.next.data);
ptr.next = ptr.next.next;
ptr.next.pre = ptr;
// Size of the linked list decreased by 1
size--;
}
// Driver code
function main() {
// Here we are creating two sentinel nodes
// (does not contain any data)
const head = new Node(null);
head.pre = null;
const tail = new Node(null);
tail.pre = head;
tail.next = null;
head.next = tail;
let n;
while (true) {
console.log("\n1. Insertion\n2. Deletion\n3. Display\n0. Exit");
n = parseInt(prompt("Enter your choice: "));
switch (n) {
case 1:
// Insertion at the beginning
// of the Doubly linked list
insertion(head, tail, 1, 10);
display(head, tail);
// Insertion at the End
// of the Doubly linked list
insertion(head, tail, size + 1, 14);
display(head, tail);
// Inserting node in between
// the doubly linked list
insertion(head, tail, 2, 8);
display(head, tail);
break;
case 2:
// Deleting the node at location 2
deletion(head, tail, 2);
display(head, tail);
// Deleting the first node
deletion(head, tail, 1);
display(head, tail);
// Deleting the last node
deletion(head, tail, size);
display(head, tail);
break;
case 3:
display(head, tail);
break;
case 0:
return;
default:
console.log("Invalid choice!");
}
}
}
// Call the main function to execute the program
main();
Python3
class Node:
def __init__(self, data=None):
self.data = data
self.next = None
self.pre = None
# Function to display all the nodes
def display(head, tail):
current = head.next
print("\nThe linked list is :- ", end="")
while current != tail:
print(current.data, end=" ")
current = current.next
# Function to insert a new node
def insertion(head, tail, n, value):
n -= 1
temp = Node(value)
ptr = head
i = 0
# Run's until reach the node after
# which we have to add the new node
while i < n:
ptr = ptr.next
i += 1
temp.next = ptr.next
temp.pre = ptr
ptr.next = temp
temp.next.pre = temp
# Linked list size is increased by 1
size[0] += 1
# Function to delete an element
# from the doubly-linked list
def deletion(head, tail, n):
n -= 1
# If linked list is empty
if head.next == tail:
print("\nerror : linked list is empty")
return
# If entered position is more
# than the size of the linked list
if n >= size[0]:
print("\nerror : position is larger"
" than size of linked list")
return
ptr = head
temp = None
i = 0
# Run's until reach the node whose
# next node have to be deleted
while i < n:
ptr = ptr.next
i += 1
print("\nDeleting node at position", n + 1,
"contains value", ptr.next.data)
temp = ptr.next.next
ptr.next = temp
temp.pre = ptr
# Size of the linked list decreased by 1
size[0] -= 1
def get_user_choice():
try:
return int(input())
except EOFError:
return 0 # Return 0 to exit the loop
# Driver code
if __name__ == "__main__":
# Here we are creating two sentinel nodes
# (does not contain any data)
head = Node()
head.pre = None
tail = Node()
tail.pre = head
tail.next = None
head.next = tail
size = [0] # To store the size of the linked list
while True:
print("\n1. Insertion\n2. Deletion\n"
"3. Display\n0. Exit")
# Prompt for user input with a default choice of 0 to exit
n = get_user_choice()
if n == 1:
# Insertion at the beginning
insertion(head, tail, 1, 10)
display(head, tail)
# Insertion at the End
insertion(head, tail, size[0] + 1, 14)
display(head, tail)
# Inserting node in between
insertion(head, tail, 2, 8)
display(head, tail)
elif n == 2:
# Deleting the node at location 2
deletion(head, tail, 2)
display(head, tail)
# Deleting the first node
deletion(head, tail, 1)
display(head, tail)
# Deleting the last node
deletion(head, tail, size[0])
display(head, tail)
elif n == 3:
display(head, tail)
else:
break
Output:
1.Insertion
2.Deletion
3.Display
0.Exit
1
The linked list is :- 10
The linked list is :- 10 14
The linked list is :- 10 8 14
1.Insertion
2.Deletion
3.Display
0.Exit
3
The linked list is :- 10 8 14
1.Insertion
2.Deletion
3.Display
0.Exit
2
Deleting node at position 2 contains value 8
The linked list is :- 10 14
Deleting node at position 1 contains value 10
The linked list is :- 14
Deleting node at position 1 contains value 14
The linked list is :-
1.Insertion
2.Deletion
3.Display
0.Exit
0