Open In App

Delete adjacent duplicate nodes from the Doubly Linked List

Last Updated : 03 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads