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<–>9Input: 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++ 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 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 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# 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 |
// 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 |
# 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. |
40 30 20
Time Complexity: O(N)
Auxiliary Space: O(1)