Open In App

XOR Linked List: Remove last node of the Linked List

Last Updated : 06 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an XOR linked list, the task is to delete the node at the end of the XOR Linked List.

Examples:

Input: 4<–>7<–>9<–>7
Output: 4<–>7<–>9
Explanation: Deleting a node from the end modifies the given XOR Linked List to 4<–>7<–>9

Input: 10
Output: List is empty
Explanation: After deleting the only node present in the XOR Linked List, the list becomes empty.

Approach: The idea to solve this problem is to traverse the XOR linked list until the last node is reached and update the address of its previous node. Follow the steps below to solve the problem:

  • If the XOR linked list is empty, then print “List is empty“.
  • Traverse the XOR Linked List until the last node of the Linked List is reached.
  • Update the address of its previous node.
  • Delete the last node from memory.
  • If the list becomes empty after deleting the last node, then print “List is empty”. Otherwise, print the remaining nodes of the linked list.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Structure of a node in XOR linked list
struct Node
{
   
    // Stores data value of a node
    int data;
   
    // Stores XOR of previous pointer and next pointer
    struct Node* nxp;
};
 
// Function to find the XOR of two nodes
struct Node* XOR(struct Node* a, struct Node* b) {
    return (struct Node*)((uintptr_t)(a) ^ (uintptr_t)(b));
}
 
// Function to insert a node with given value at given position
struct Node* insert(struct Node** head, int value)
{
   
    // If XOR linked list is empty
    if (*head == NULL)
    {
       
        // Initialize a new Node
        struct Node* node = new Node;
       
        // Stores data value in the node
        node->data = value;
       
        // Stores XOR of previous and next pointer
        node->nxp = XOR(NULL, NULL);
       
        // Update pointer of head node
        *head = node;
    }
 
    // If the XOR linked list is not empty
    else
    {
       
        // Stores the address of current node
        struct Node* curr = *head;
       
        // Stores the address of previous node
        struct Node* prev = NULL;
       
        // Initialize a new Node
        struct Node* node = new Node;
       
        // Update curr node address
        curr->nxp = XOR(node, XOR(NULL, curr->nxp));
       
        // Update new node address
        node->nxp = XOR(NULL, curr);
       
        // Update head
        *head = node;
       
        // Update data value of current node
        node->data = value;
    }
    return *head;
}
 
// Function to print elements of the XOR Linked List
void printList(struct Node** head)
{
    // Stores XOR pointer in current node
    struct Node* curr = *head;
   
    // Stores XOR pointer of in previous Node
    struct Node* prev = NULL;
    // Stores XOR pointer of in next node
    struct Node* next;
    // Traverse XOR linked list
    while (curr != NULL) {
        // Print current node
        cout << curr->data << " ";
        // Forward traversal
        next = XOR(prev, curr->nxp);
        // Update prev
        prev = curr;
        // Update curr
        curr = next;
    }
}
 
// Function to delete the last node present in the XOR Linked List
struct Node* delEnd(struct Node** head)
{
    // Base condition
    if (*head == NULL)
        cout << "List is empty";
    else
    {
       
        // Stores XOR pointer in current node
        struct Node* curr = *head;
       
        // Stores XOR pointer of in previous Node
        struct Node* prev = NULL;
       
        // Stores XOR pointer of in next node
        struct Node* next;
       
        // Traverse XOR linked list
        while (XOR(curr->nxp, prev) != NULL)
        {
            // Forward traversal
            next = XOR(prev, curr->nxp);
           
            // Update prev
            prev = curr;
           
            // Update curr
            curr = next;
        }
        // If the Linked List contains more than 1 node
        if (prev != NULL) {
            prev->nxp = XOR(XOR(prev->nxp, curr), NULL);
        }
        // Otherwise
        else {
            *head = NULL;
        }
 
        // Delete the last node from memory
        delete(curr);
    }
 
    // Returns head of new linked list
    return *head;
}
 
// Driver Code
int main()
{
 
    /* Create the XOR Linked List
    head-->40<-->30<-->20<-->10 */
    struct Node* head = NULL;
    insert(&head, 10);
    insert(&head, 20);
    insert(&head, 30);
    insert(&head, 40);
 
    delEnd(&head);
 
    // If the list had a single node
    if (head == NULL)
        cout << "List is empty";
    else
        // Print the list after deletion
        printList(&head);
 
    return (0);
}
 
// This code is contributed by ajaymakvana


C




// C program for the above approach
 
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
 
// Structure of a node
// in XOR linked list
struct Node {
 
    // Stores data value
    // of a node
    int data;
 
    // Stores XOR of previous
    // pointer and next pointer
    struct Node* nxp;
};
 
// Function to find the XOR of two nodes
struct Node* XOR(struct Node* a, struct Node* b)
{
    return (struct Node*)((uintptr_t)(a)
                          ^ (uintptr_t)(b));
}
 
// Function to insert a node with
// given value at given position
struct Node* insert(struct Node** head, int value)
{
    // If XOR linked list is empty
    if (*head == NULL) {
 
        // Initialize a new Node
        struct Node* node
            = (struct Node*)malloc(
                sizeof(struct Node));
 
        // Stores data value in
        // the node
        node->data = value;
 
        // Stores XOR of previous
        // and next pointer
        node->nxp = XOR(NULL, NULL);
 
        // Update pointer of head node
        *head = node;
    }
 
    // If the XOR linked list
    // is not empty
    else {
 
        // Stores the address
        // of current node
        struct Node* curr = *head;
 
        // Stores the address
        // of previous node
        struct Node* prev = NULL;
 
        // Initialize a new Node
        struct Node* node
            = (struct Node*)malloc(
                sizeof(struct Node));
 
        // Update curr node address
        curr->nxp = XOR(node,
                        XOR(NULL, curr->nxp));
 
        // Update new node address
        node->nxp = XOR(NULL, curr);
 
        // Update head
        *head = node;
 
        // Update data value of
        // current node
        node->data = value;
    }
    return *head;
}
 
// Function to print elements of
// the XOR Linked List
void printList(struct Node** head)
{
    // Stores XOR pointer
    // in current node
    struct Node* curr = *head;
 
    // Stores XOR pointer of
    // in previous Node
    struct Node* prev = NULL;
 
    // Stores XOR pointer of
    // in next node
    struct Node* next;
 
    // Traverse XOR linked list
    while (curr != NULL) {
 
        // Print current node
        printf("%d ", curr->data);
 
        // Forward traversal
        next = XOR(prev, curr->nxp);
 
        // Update prev
        prev = curr;
 
        // Update curr
        curr = next;
    }
}
 
// Function to delete the last node
// present in the XOR Linked List
struct Node* delEnd(struct Node** head)
{
    // Base condition
    if (*head == NULL)
        printf("List is empty");
    else {
 
        // Stores XOR pointer
        // in current node
        struct Node* curr = *head;
 
        // Stores XOR pointer of
        // in previous Node
        struct Node* prev = NULL;
 
        // Stores XOR pointer of
        // in next node
        struct Node* next;
 
        // Traverse XOR linked list
        while (XOR(curr->nxp, prev) != NULL) {
 
            // Forward traversal
            next = XOR(prev, curr->nxp);
 
            // Update prev
            prev = curr;
 
            // Update curr
            curr = next;
        }
        // If the Linked List contains more than 1 node
        if (prev != NULL)
            prev->nxp = XOR(XOR(prev->nxp, curr), NULL);
 
        // Otherwise
        else
            *head = NULL;
 
        // Delete the last node from memory
        free(curr);
    }
 
    // Returns head of new linked list
    return *head;
}
 
// Driver Code
int main()
{
 
    /* Create the XOR Linked List
    head-->40<-->30<-->20<-->10 */
    struct Node* head = NULL;
    insert(&head, 10);
    insert(&head, 20);
    insert(&head, 30);
    insert(&head, 40);
 
    delEnd(&head);
 
    // If the list had a single node
    if (head == NULL)
        printf("List is empty");
    else
        // Print the list after deletion
        printList(&head);
 
    return (0);
}


Java




// Java program for the above approach
import java.util.*;
 
// Structure of a node in XOR linked list
class Node {
    int value;
    int npx;
 
    // Constructor to initialize node
    Node(int value)
    {
        this.value = value;
        this.npx = 0;
    }
}
 
// create linked list class
class XorLinkedList {
 
    Node head;
    Node tail;
    List<Node> nodes;
 
    // constructor
    XorLinkedList()
    {
        this.head = null;
        this.tail = null;
        this.nodes = new ArrayList<>();
    }
 
    // Function to insert a node with given value at given
    // position
    void insert(int value)
    {
        // Initialize a new Node
        Node node = new Node(value);
 
        // Check If XOR linked list is empty
        if (head == null) {
            // Update pointer of head node
            head = node;
            // Update pointer of tail node
            tail = node;
        }
        else {
            // Update curr node address
            head.npx = node.hashCode() ^ head.npx;
 
            // Update new node address
            node.npx = head.hashCode();
 
            // Update head
            head = node;
        }
        // push node
        nodes.add(node);
    }
 
    // Function to print elements of the XOR Linked List
    void printList()
    {
        if (head != null) {
            int prevId = 0;
            Node node = head;
            int nextId = 1;
            System.out.print(node.value + " ");
 
            // Traverse XOR linked list
            while (nextId != 0) {
                // Forward traversal
                nextId = prevId ^ node.npx;
 
                if (nextId != 0) {
                    // Update prev
                    prevId = node.hashCode();
 
                    // Update curr
                    node = typeCast(nextId);
 
                    // Print current node
                    System.out.print(node.value + " ");
                }
                else {
                    return;
                }
            }
        }
    }
 
    // method to check if the linked list is empty or not
    boolean isEmpty() { return head == null; }
 
    // method to return a new instance of type
    Node typeCast(int id)
    {
        for (Node n : nodes) {
            if (n.hashCode() == id) {
                return n;
            }
        }
        return null;
    }
 
    // Function to delete the last node present in the XOR
    // Linked List
    int delEnd()
    {
        // If list is empty
        if (isEmpty()) {
            return -1; // Return -1 indicating list is empty
        }
        // If list has 1 node
        else if (head == tail) {
            int value = head.value;
            head = tail = null;
            return value;
        }
        // If list has 2 nodes
        else if (typeCast(0 ^ head.npx) == tail) {
            int value = head.value;
            tail = head;
            head.npx = tail.npx = 0;
            return value;
        }
        // If list has more than 2 nodes
        else {
            // Stores XOR pointer of in previous Node
            int prevId = 0;
 
            // Stores XOR pointer in current node
            Node node = head;
 
            // Stores XOR pointer of in next node
            int nextId = 1;
 
            // Traverse XOR linked list
            while (nextId != 0) {
                // Forward traversal
                nextId = prevId ^ node.npx;
                if (nextId != 0) {
                    // Update prev
                    prevId = node.hashCode();
 
                    // Update curr
                    node = typeCast(nextId);
                }
            }
            // update res, x, y, and tail.
            int res = node.value;
            int x = typeCast(prevId).npx ^ node.hashCode();
            Node y = typeCast(prevId);
            y.npx = x ^ 0;
            tail = y;
            return res;
        }
    }
}
 
public class GFG {
 
    // Driver code
    public static void main(String[] args)
    {
        // Create following XOR Linked List
        // head-->40<-->30<-->20<-->10
        XorLinkedList head = new XorLinkedList();
        head.insert(10);
        head.insert(20);
        head.insert(30);
        head.insert(40);
 
        // Delete the first node
        head.delEnd();
 
        // Print the following XOR Linked List
        // head-->30<-->20<-->10
        if (head.isEmpty()) {
            System.out.println("List is empty");
        }
        else {
            // Print the list after deletion
            head.printList();
        }
    }
}
 
// This code is contributed by Susobhan Akhuli


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
// Structure of a node in XOR linked list
class Node {
    public int value;
    public int npx;
 
    // Constructor to initialize node
    public Node(int value)
    {
        this.value = value;
        this.npx = 0;
    }
}
 
// Class for XOR linked list
class XorLinkedList {
    private Node head;
    private Node tail;
    private List<Node> nodes;
 
    // Constructor
    public XorLinkedList()
    {
        head = null;
        tail = null;
        nodes = new List<Node>();
    }
 
    // Function to insert a node with given value at the
    // beginning
    public void Insert(int value)
    {
        Node node = new Node(value);
        if (head == null) {
            head = node;
            tail = node;
        }
        else {
            head.npx = node.GetHashCode() ^ head.npx;
            node.npx = head.GetHashCode();
            head = node;
        }
        nodes.Add(node);
    }
 
    // Function to print elements of the XOR Linked List
    public void PrintList()
    {
        if (head != null) {
            int prevId = 0;
            Node node = head;
            int nextId = 1;
            Console.Write(node.value + " ");
            while (nextId != 0) {
                nextId = prevId ^ node.npx;
                if (nextId != 0) {
                    prevId = node.GetHashCode();
                    node = TypeCast(nextId);
                    Console.Write(node.value + " ");
                }
                else {
                    return;
                }
            }
        }
    }
 
    // Method to check if the linked list is empty
    public bool IsEmpty() { return head == null; }
 
    // Method to return a new instance of type Node
    private Node TypeCast(int id)
    {
        foreach(Node n in nodes)
        {
            if (n.GetHashCode() == id) {
                return n;
            }
        }
        return null;
    }
 
    // Function to delete the last node present in the XOR
    // Linked List
    public int DelEnd()
    {
        if (IsEmpty()) {
            return -1; // Return -1 indicating list is empty
        }
        else if (head == tail) {
            int value = head.value;
            head = tail = null;
            return value;
        }
        else if (TypeCast(0 ^ head.npx) == tail) {
            int value = head.value;
            tail = head;
            head.npx = tail.npx = 0;
            return value;
        }
        else {
            int prevId = 0;
            Node node = head;
            int nextId = 1;
            while (nextId != 0) {
                nextId = prevId ^ node.npx;
                if (nextId != 0) {
                    prevId = node.GetHashCode();
                    node = TypeCast(nextId);
                }
            }
            int res = node.value;
            int x
                = TypeCast(prevId).npx ^ node.GetHashCode();
            Node y = TypeCast(prevId);
            y.npx = x ^ 0;
            tail = y;
            return res;
        }
    }
}
 
public class GFG {
    // Driver code
    public static void Main(string[] args)
    {
        // Create XOR Linked List: head --> 40 <--> 30 <-->
        // 20 <--> 10
        XorLinkedList head = new XorLinkedList();
        head.Insert(10);
        head.Insert(20);
        head.Insert(30);
        head.Insert(40);
 
        // Delete the first node
        head.DelEnd();
 
        // Print XOR Linked List: head --> 30 <--> 20 <-->
        // 10
        if (head.IsEmpty()) {
            Console.WriteLine("List is empty");
        }
        else {
            head.PrintList();
        }
    }
}
 
// This code is contributed by Susobhan Akhuli


Javascript




// Define a class for the Node
class Node {
    constructor(value) {
        this.value = value;
        this.npx = 0;
    }
}
 
// Define a class for the XOR Linked List
class XorLinkedList {
    constructor() {
        this.head = null;
        this.tail = null;
        this.nodes = [];
    }
 
    // Function to insert a node with given value
    insert(value) {
        let node = new Node(value);
        this.nodes.push(node);
        if(this.head === null){
            this.tail = node;
        }
        if (this.head !== null) {
            node.npx = getPointer(this.head);
            this.head.npx = getPointer(node) ^ this.head.npx;
        }
        this.head = node;
    }
 
    // Function to print elements of the XOR Linked List in the same line
    printList() {
        let current = this.head;
        let prevAddr = null;
        let output = ""; // Initialize an empty string for concatenation
         
        while (current) {
            output += current.value + " "; // Concatenate the current value with a space
            let nextAddr = prevAddr ^ current.npx;
            prevAddr = getPointer(current);
            current = dereferencePointer(nextAddr);
        }
        console.log(output); // Print the concatenated string containing all values
    }
 
    // Method to check if the linked list is empty
    isEmpty() {
        return !this.head;
    }
         
    // Function to delete the last node present in the XOR Linked List
    delEnd() {
        if (this.isEmpty()) {
            return -1;
        } else if (this.head === this.tail) {
            let value = this.head.value;
            this.head = this.tail = null;
            return value;
        } else {
            let secLastNodeId = this.nodes[this.nodes.indexOf(this.tail)-1];
            var res = this.nodes.shift();
            addressMap.delete(this.tail);
            delete this.tail;
            this.tail = secLastNodeId;
            return res;
        }
    }
}
 
let addressMap = new Map();
let addressCount = 1;
  
function getPointer(object) {
    if (addressMap.has(object)) return addressMap.get(object);
  
    let newAddressCountValue = addressCount++;
    addressMap.set(object, newAddressCountValue);
  
    return newAddressCountValue;
}
  
function dereferencePointer(address) {
   for (let [key, value] of addressMap.entries()) {
       if (value === address) return key;
   }
   return undefined;
}
 
// Create XOR Linked List
let xll = new XorLinkedList();
 
// Insert elements into XOR Linked List
// 40->30->20->10
xll.insert(10);
xll.insert(20);
xll.insert(30);
xll.insert(40);
 
// Delete the last node
xll.delEnd();
 
// Print the XOR Linked List
if (xll.isEmpty()) {
    console.log("List is empty");
} else {
    // Print the list after deletion
    xll.printList();
}
 
// This code is contributed by Susobhan Akhuli


Python3




# Python implementation of the above approach.
import ctypes
 
 
# Structure of a node in XOR linked list
class Node:
     
    def __init__(self, value):
        self.value = value
        self.npx = 0
 
 
# create linked list class
class XorLinkedList:
  
    # constructor
    def __init__(self):
        self.head = None
        self.tail = None
        self.__nodes = []
         
     
    # Function to insert a node with given value at given position
    def insert(self, value):
         
        # Initialize a new Node
        node = Node(value)
         
        # Check If XOR linked list is empty
        if self.head is None:
             
            # Update pointer of head node
            self.head = node
             
            # Update pointer of tail node
            self.tail = node
             
        else:
             
            # Update curr node address
            self.head.npx = id(node) ^ self.head.npx
             
            # Update new node address
            node.npx = id(self.head)
             
            # Update head
            self.head = node
             
        # push node
        self.__nodes.append(node)
         
     
    # Function to print elements of the XOR Linked List
    def printList(self):
  
         
        if self.head != None:
            prev_id = 0
            node = self.head
            next_id = 1
            print(node.value, end=' ')
             
            # Traverse XOR linked list
            while next_id:
                 
                # Forward traversal
                next_id = prev_id ^ node.npx
                 
                if next_id:
                     
                    # Update prev
                    prev_id = id(node)
                     
                    # Update curr
                    node = self.__type_cast(next_id)
                     
                    # Print current node
                    print(node.value, end=' ')
                else:
                    return
 
                 
    # method to check if the linked list is empty or not
    def isEmpty(self):
        if self.head is None:
            return True
        return False
     
    # method to return a new instance of type
    def __type_cast(self, id):
        return ctypes.cast(id, ctypes.py_object).value
     
     
    # Function to delete the last node present in the XOR Linked List
    def delEnd(self):
         
        # If list is empty
        if self.isEmpty(): 
            return "List is empty !"
         
        # If list has 1 node
        elif self.head == self.tail:
            self.head = self.tail = None
         
        # If list has 2 nodes
        elif self.__type_cast(0 ^ self.head.npx) == (self.tail):
            self.tail = self.head
            self.head.npx = self.tail.npx = 0
             
        # If list has more than 2 nodes
        else
            # Stores XOR pointer of in previous Node
            prev_id = 0
             
            # Stores XOR pointer in current node
            node = self.head
             
            # Stores XOR pointer of in next node
            next_id = 1
             
            # Traverse XOR linked list
            while next_id:
                 
                # Forward traversal
                next_id = prev_id ^ node.npx
                if next_id:
                     
                    # Update prev
                    prev_id = id(node)
                     
                    # Update curr
                    node = self.__type_cast(next_id)
                     
            # update res, x, y, and tail.             
            res = node.value
            x = self.__type_cast(prev_id).npx ^ id(node)
            y = self.__type_cast(prev_id)
            y.npx = x ^ 0
            self.tail = y
            return res
         
 
# Create following XOR Linked List
# head-->40<-->30<-->20<-->10
head = XorLinkedList()
head.insert(10)
head.insert(20)
head.insert(30)
head.insert(40)
 
# Delete the first node
head.delEnd();
 
 
# Print the following XOR Linked List
# head-->30<-->20<-->10
if (head == None):
    print("List is empty")
else:
    # Print the list after deletion
    head.printList();
 
 
# This code is contributed by Nighi goel.


Output

40 30 20 


Time Complexity: O(N)
Auxiliary Space: O(1)



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

Similar Reads