Delete adjacent duplicate nodes from the Doubly Linked List
Last Updated :
03 Apr, 2023
Given a doubly linked list. The problem is to remove all adjacent duplicate nodes from the list such that the final modified doubly linked list does not contain any adjacent duplicate nodes. Examples:
Approach: The approach uses stack to keep track of the adjacent nodes at any point in the modified Doubly Linked List. Algorithm:
delAdjacentDuplicates(head_ref)
Create an empty stack st
Declare current, next, top
current = head_ref
while current != NULL
if isEmpty(st) or current->data != peek(st)->data
push current on to the stack st
current = current->next
else
next = current->next
top = peek(st)
pop element from st
delete node 'current'
delete node 'top'
current = next
peek(st) operation returns the value at the top of the stack. The algorithm to delete a node n from the doubly linked list using pointer to the node n is discussed in this post.
C++
/* C++ implementation to delete adjacent duplicate nodes
from the Doubly Linked List */
#include <bits/stdc++.h>
using namespace std;
/* a node of the doubly linked list */
struct Node {
int data;
struct Node* next;
struct Node* prev;
};
/* Function to delete a node in a Doubly Linked List.
head_ref --> pointer to head node pointer.
del --> pointer to node to be deleted. */
void deleteNode(struct Node** head_ref, struct Node* del)
{
/* base case */
if (*head_ref == NULL || del == NULL)
return;
/* If node to be deleted is head node */
if (*head_ref == del)
*head_ref = del->next;
/* Change next only if node to be deleted is NOT the last node */
if (del->next != NULL)
del->next->prev = del->prev;
/* Change prev only if node to be deleted is NOT the first node */
if (del->prev != NULL)
del->prev->next = del->next;
/* Finally, free the memory occupied by del*/
free(del);
}
/* function to delete adjacent duplicate nodes from
the Doubly Linked List */
void delAdjacentDupNodes(struct Node** head_ref)
{
// an empty stack 'st'
stack<Node*> st;
struct Node* current = *head_ref;
/* traverse the doubly linked list */
while (current != NULL) {
/* if stack 'st' is empty or if current->data != st.top()->data
push 'current' on to the stack 'st' */
if (st.empty() || current->data != st.top()->data) {
st.push(current);
/* move to the next node */
current = current->next;
}
// else current->data == st.top()->data
else {
/* pointer to the node next to the 'current' node */
struct Node* next = current->next;
/* pointer to the node at the top of 'st' */
struct Node* top = st.top();
/* remove top element from 'st' */
st.pop();
/* delete 'current' node from the list */
deleteNode(head_ref, current);
/* delete 'top' node from the list */
deleteNode(head_ref, top);
/* update 'current' */
current = next;
}
}
}
/* Function to insert a node at the beginning
of the Doubly Linked List */
void push(struct Node** head_ref, int new_data)
{
/* allocate node */
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
/* put in the data */
new_node->data = new_data;
/* since we are adding at the beginning,
prev is always NULL */
new_node->prev = NULL;
/* link the old list of the new node */
new_node->next = (*head_ref);
/* change prev of head node to new node */
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Function to print nodes in a given doubly linked list */
void printList(struct Node* head)
{
if (head == NULL)
cout << "Empty Doubly Linked List";
while (head != NULL) {
cout << head->data << " ";
head = head->next;
}
}
/* Driver program to test above functions*/
int main()
{
/* Start with the empty list */
struct Node* head = NULL;
/* Create the doubly linked list 10<->8<->4<->4<->8<->5 */
push(&head, 5);
push(&head, 8);
push(&head, 4);
push(&head, 4);
push(&head, 8);
push(&head, 10);
cout << "Doubly linked list before deletion:n";
printList(head);
/* delete adjacent duplicate nodes */
delAdjacentDupNodes(&head);
cout << "nDoubly linked list after deletion:n";
printList(head);
return 0;
}
Java
import java.util.*;
class Node {
int data;
Node next;
Node prev;
}
class Main {
static void deleteNode(Node head_ref[], Node del) {
if (head_ref[0] == null || del == null) {
return;
}
if (head_ref[0] == del) {
head_ref[0] = del.next;
}
if (del.next != null) {
del.next.prev = del.prev;
}
if (del.prev != null) {
del.prev.next = del.next;
}
del = null;
}
static void delAdjacentDupNodes(Node head_ref[]) {
Stack<Node> st = new Stack<>();
Node current = head_ref[0];
while (current != null) {
if (st.empty() || current.data != st.peek().data) {
st.push(current);
current = current.next;
} else {
Node next = current.next;
Node top = st.peek();
st.pop();
deleteNode(head_ref, current);
deleteNode(head_ref, top);
current = next;
}
}
}
static void push(Node head_ref[], int new_data) {
Node new_node = new Node();
new_node.data = new_data;
new_node.prev = null;
new_node.next = head_ref[0];
if (head_ref[0] != null) {
head_ref[0].prev = new_node;
}
head_ref[0] = new_node;
}
static void printList(Node head) {
if (head == null) {
System.out.println("Empty Doubly Linked List");
}
while (head != null) {
System.out.print(head.data + " ");
head = head.next;
}
}
public static void main(String args[]) {
Node[] head = new Node[1];
head[0] = null;
push(head, 5);
push(head, 8);
push(head, 4);
push(head, 4);
push(head, 8);
push(head, 10);
System.out.println("Doubly linked list before deletion:");
printList(head[0]);
delAdjacentDupNodes(head);
System.out.println("\nDoubly linked list after deletion:");
printList(head[0]);
}
}
C#
/* C# implementation to delete adjacent duplicate nodes
from the Doubly Linked List */
using System;
/* a node of the doubly linked list */
public class Node
{
public int data;
public Node next;
public Node prev;
};
public class Program
{
/* Function to delete a node in a Doubly Linked List.
head_ref --> pointer to head node pointer.
del --> pointer to node to be deleted. */
static void deleteNode(ref Node head_ref, Node del)
{
/* base case */
if (head_ref == null || del == null)
return;
/* If node to be deleted is head node */
if (head_ref == del)
head_ref = del.next;
/* Change next only if node to be deleted is NOT the last node */
if (del.next != null)
del.next.prev = del.prev;
/* Change prev only if node to be deleted is NOT the first node */
if (del.prev != null)
del.prev.next = del.next;
/* Finally, free the memory occupied by del*/
del = null;
}
/* function to delete adjacent duplicate nodes from
the Doubly Linked List */
static void delAdjacentDupNodes(ref Node head_ref)
{
// an empty stack 'st'
var st = new System.Collections.Generic.Stack<Node>();
Node current = head_ref;
/* traverse the doubly linked list */
while (current != null)
{
/* if stack 'st' is empty or if current->data != st.top()->data
push 'current' on to the stack 'st' */
if (st.Count == 0 || current.data != st.Peek().data)
{
st.Push(current);
/* move to the next node */
current = current.next;
}
// else current->data == st.top()->data
else
{
/* pointer to the node next to the 'current' node */
Node next = current.next;
/* pointer to the node at the top of 'st' */
/* remove top element from 'st' */
Node top = st.Pop();
/* delete 'current' node from the list */
deleteNode(ref head_ref, current);
/* delete 'top' node from the list */
deleteNode(ref head_ref, top);
/* update 'current' */
current = next;
}
}
}
/* Function to insert a node at the beginning
of the Doubly Linked List */
static void push(ref Node head_ref, int new_data)
{
/* allocate node */
Node new_node = new Node();
/* put in the data */
new_node.data = new_data;
/* since we are adding at the beginning,
prev is always NULL */
new_node.prev = null;
/* link the old list of the new node */
new_node.next = head_ref;
/* change prev of head node to new node */
if (head_ref != null)
head_ref.prev = new_node;
/* move the head to point to the new node */
head_ref = new_node;
}
/* Function to print nodes in a given doubly linked list */
static void printList(Node head)
{
if (head == null)
Console.WriteLine("Empty Doubly Linked List");
while (head != null)
{
Console.Write(head.data + " ");
head = head.next;
}
}
/* Driver program to test above functions*/
static void Main(string[] args)
{
/* Start with the empty list */
Node head = null;
/* Create the doubly linked list 10<->8<->4<->4<->8<->5 */
push(ref head, 5);
push(ref head, 8);
push(ref head, 4);
push(ref head, 4);
push(ref head, 8);
push(ref head, 10);
Console.WriteLine("Doubly linked list before deletion:");
printList(head);
/* delete adjacent duplicate nodes */
delAdjacentDupNodes(ref head);
Console.WriteLine("\nDoubly linked list after deletion:");
printList(head);
}
}
Python3
class Node:
def __init__(self):
self.data = 0
self.next = None
self.prev = None
def deleteNode(head_ref, del_node):
if not head_ref or not del_node:
return
if head_ref[0] == del_node:
head_ref[0] = del_node.next
if del_node.next:
del_node.next.prev = del_node.prev
if del_node.prev:
del_node.prev.next = del_node.next
del_node = None
def delAdjacentDupNodes(head_ref):
st = []
current = head_ref[0]
while current:
if not st or current.data != st[-1].data:
st.append(current)
current = current.next
else:
nxt = current.next
top = st.pop()
deleteNode(head_ref, current)
deleteNode(head_ref, top)
current = nxt
def push(head_ref, new_data):
new_node = Node()
new_node.data = new_data
new_node.prev = None
new_node.next = head_ref[0]
if head_ref[0]:
head_ref[0].prev = new_node
head_ref[0] = new_node
def printList(head):
if not head:
print("Empty Doubly Linked List")
else:
while head:
print(head.data, end=" ")
head = head.next
print()
if __name__ == '__main__':
head = [None]
push(head, 5)
push(head, 8)
push(head, 4)
push(head, 4)
push(head, 8)
push(head, 10)
print("Doubly linked list before deletion:")
printList(head[0])
delAdjacentDupNodes(head)
print("Doubly linked list after deletion:")
printList(head[0])
JavaScript
// Javascript code addition
/* a node of the doubly linked list */
class Node {
constructor(data) {
this.data = data;
this.next = null;
this.prev = null;
}
}
/* Function to delete a node in a Doubly Linked List.
head_ref --> pointer to head node pointer.
del --> pointer to node to be deleted. */
function deleteNode(head_ref, del) {
/* base case */
if (head_ref == null || del == null) {
return;
}
/* If node to be deleted is head node */
if (head_ref == del) {
head_ref = del.next;
}
/* Change next only if node to be deleted is NOT the last node */
if (del.next != null) {
del.next.prev = del.prev;
}
/* Change prev only if node to be deleted is NOT the first node */
if (del.prev != null) {
del.prev.next = del.next;
}
/* Finally, free the memory occupied by del*/
del = null;
}
/* function to delete adjacent duplicate nodes from the Doubly Linked List */
function delAdjacentDupNodes(head_ref) {
// an empty stack 'st'
let st = [];
let current = head_ref;
/* traverse the doubly linked list */
while (current != null) {
/* if stack 'st' is empty or if current.data != st.top().data
push 'current' on to the stack 'st' */
if (st.length == 0 || current.data != st[st.length - 1].data) {
st.push(current);
/* move to the next node */
current = current.next;
}
// else current.data == st.top().data
else {
/* pointer to the node next to the 'current' node */
let next = current.next;
/* pointer to the node at the top of 'st' */
/* remove top element from 'st' */
let top = st.pop();
/* delete 'current' node from the list */
deleteNode(head_ref, current);
/* delete 'top' node from the list */
deleteNode(head_ref, top);
/* update 'current' */
current = next;
}
}
}
/* Function to insert a node at the beginning of the Doubly Linked List */
function push(head_ref, new_data) {
/* allocate node */
let new_node = new Node(new_data);
/* link the old list of the new node */
new_node.next = head_ref;
/* change prev of head node to new node */
if (head_ref != null) {
head_ref.prev = new_node;
}
/* move the head to point to the new node */
head_ref = new_node;
return head_ref;
}
/* Function to print nodes in a given doubly linked list */
function printList(head) {
if (head == null) {
console.log("Empty Doubly Linked List");
return;
}
let output = "";
while (head != null) {
output += head.data + " ";
head = head.next;
}
console.log(output);
}
/* Driver program to test above functions*/
/* Start with the empty list */
let head = null;
/* Create the doubly linked list 10<->8<->4<->4<->8<->5 */
head = push(head, 5);
head = push(head, 8);
head = push(head, 4);
head = push(head, 4);
head = push(head, 8);
head = push(head, 10);
console.log("Doubly linked list before deletion:");
printList(head);
/* delete adjacent duplicate nodes */
delAdjacentDupNodes(head);
console.log("\nDoubly linked list after deletion:");
printList(head);
// The code is contributed by Nidhi goel.
Output:
Doubly linked list before deletion:
10 8 4 4 8 5
Doubly linked list after deletion:
10 5
Time Complexity: O(n) Auxiliary Space: O(n), in worst case when there are no adjacent duplicate nodes.