Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Swap KTH Node From Beginning With KTH Node From End in A Linked List

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 63

Swap Kth node from beginning with Kth node from

end in a Linked List


Given a singly linked list, swap kth node from beginning with kth node from
end. Swapping of data is not allowed, only pointers should be changed. This
requirement may be logical in many situations where the linked list data part is huge
(For example student details line Name, RollNo, Address, ..etc). The pointers are
always fixed (4 bytes for most of the compilers).

The problem seems simple at first look, but it has many interesting cases.
Let X be the kth node from beginning and Y be the kth node from end. Following are
the interesting cases that must be handled.
1) Y is next to X
2) X is next to Y
3) X and Y are same
4) X and Y don’t exist (k is more than number of nodes in linked list)

// A C++ program to swap Kth node from beginning with kth node from end
#include <iostream>
#include <stdlib.h>
using namespace std;

// A Linked List node


struct Node
{
int data;
struct Node *next;
};

/* Utility function to insert a node at the beginning */


void push(struct Node **head_ref, int new_data)
{
struct Node *new_node = (struct Node *) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}

/* Utility function for displaying linked list */


void printList(struct Node *node)
{
while (node != NULL)
{
cout << node->data << " ";
node = node->next;
}
cout << endl;
}

/* Utility function for calculating length of linked list */


int countNodes(struct Node *s)
{
int count = 0;
while (s != NULL)
{
count++;
s = s->next;
}
return count;
}

/* Function for swapping kth nodes from both ends of linked list */
void swapKth(struct Node **head_ref, int k)
{
// Count nodes in linked list
int n = countNodes(*head_ref);

// Check if k is valid
if (n < k) return;

// If x (kth node from start) and y(kth node from end) are same
if (2*k - 1 == n) return;

// Find the kth node from beginning of linked list. We also find
// previous of kth node because we need to update next pointer of
// the previous.
Node *x = *head_ref;
Node *x_prev = NULL;
for (int i = 1; i < k; i++)
{
x_prev = x;
x = x->next;
}

// Similarly, find the kth node from end and its previous. kth node
// from end is (n-k+1)th node from beginning
Node *y = *head_ref;
Node *y_prev = NULL;
for (int i = 1; i < n-k+1; i++)
{
y_prev = y;
y = y->next;
}

// If x_prev exists, then new next of it will be y. Consider the case


// when y->next is x, in this case, x_prev and y are same. So the
statement
// "x_prev->next = y" creates a self loop. This self loop will be
broken
// when we change y->next.
if (x_prev)
x_prev->next = y;

// Same thing applies to y_prev


if (y_prev)
y_prev->next = x;

// Swap next pointers of x and y. These statements also break self


// loop if x->next is y or y->next is x
Node *temp = x->next;
x->next = y->next;
y->next = temp;
// Change head pointers when k is 1 or n
if (k == 1)
*head_ref = y;
if (k == n)
*head_ref = x;
}

// Driver program to test above functions


int main()
{
// Let us create the following linked list for testing
// 1->2->3->4->5->6->7->8
struct Node *head = NULL;
for (int i = 8; i >= 1; i--)
push(&head, i);

cout << "Original Linked List: ";


printList(head);

for (int k = 1; k < 9; k++)


{
swapKth(&head, k);
cout << "\nModified List for k = " << k << endl;
printList(head);
}

return 0;
}
Output:
Original Linked List: 1 2 3 4 5 6 7 8

Modified List for k = 1


8 2 3 4 5 6 7 1

Modified List for k = 2


8 7 3 4 5 6 2 1

Modified List for k = 3


8 7 6 4 5 3 2 1

Modified List for k = 4


8 7 6 5 4 3 2 1

Modified List for k = 5


8 7 6 4 5 3 2 1
Modified List for k = 6
8 7 3 4 5 6 2 1

Modified List for k = 7


8 2 3 4 5 6 7 1

Modified List for k = 8


1 2 3 4 5 6 7 8

Merge Sort for Doubly Linked List


Given a doubly linked list, write a function to sort the doubly linked list in increasing
order using merge sort.
For example, the following doubly linked list should be changed to 24810

// C++ program for merge sort on doubly linked list


#include <bits/stdc++.h>
using namespace std;
class Node
{
public:
int data;
Node *next, *prev;
};

Node *split(Node *head);

// Function to merge two linked lists


Node *merge(Node *first, Node *second)
{
// If first linked list is empty
if (!first)
return second;

// If second linked list is empty


if (!second)
return first;

// Pick the smaller value


if (first->data < second->data)
{
first->next = merge(first->next,second);
first->next->prev = first;
first->prev = NULL;
return first;
}
else
{
second->next = merge(first,second->next);
second->next->prev = second;
second->prev = NULL;
return second;
}
}

// Function to do merge sort


Node *mergeSort(Node *head)
{
if (!head || !head->next)
return head;
Node *second = split(head);

// Recur for left and right halves


head = mergeSort(head);
second = mergeSort(second);

// Merge the two sorted halves


return merge(head,second);
}

// A utility function to insert a new node at the


// beginning of doubly linked list
void insert(Node **head, int data)
{
Node *temp = new Node();
temp->data = data;
temp->next = temp->prev = NULL;
if (!(*head))
(*head) = temp;
else
{
temp->next = *head;
(*head)->prev = temp;
(*head) = temp;
}
}

// A utility function to print a doubly linked list in


// both forward and backward directions
void print(Node *head)
{
Node *temp = head;
cout<<"Forward Traversal using next poitner\n";
while (head)
{
cout << head->data << " ";
temp = head;
head = head->next;
}
cout << "\nBackward Traversal using prev pointer\n";
while (temp)
{
cout << temp->data << " ";
temp = temp->prev;
}
}

// Utility function to swap two integers


void swap(int *A, int *B)
{
int temp = *A;
*A = *B;
*B = temp;
}

// Split a doubly linked list (DLL) into 2 DLLs of


// half sizes
Node *split(Node *head)
{
Node *fast = head,*slow = head;
while (fast->next && fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
}
Node *temp = slow->next;
slow->next = NULL;
return temp;
}

// Driver program
int main(void)
{
Node *head = NULL;
insert(&head, 5);
insert(&head, 20);
insert(&head, 4);
insert(&head, 3);
insert(&head, 30);
insert(&head, 10);
head = mergeSort(head);
cout << "Linked List after sorting\n";
print(head);
return 0;
}

// This is code is contributed by rathbhupendra

Output:
Linked List after sorting
Forward Traversal using next pointer
3 4 5 10 20 30
Backward Traversal using prev pointer
30 20 10 5 4 3
Thanks to Goku for providing above implementation in a comment here.
Time Complexity: Time complexity of the above implementation is same as time
complexity of MergeSort for arrays. It takes Θ(nLogn) time.

Find pairs with given sum in doubly linked list


Given a sorted doubly linked list of positive distinct elements, the task is to find pairs
in doubly linked list whose sum is equal to given value x, without using any extra
space ?
Example:
Input : head : 1 <-> 2 <-> 4 <-> 5 <-> 6 <-> 8 <-> 9
x = 7
Output: (6, 1), (5,2)
Expected time complexity is O(n) and auxiliary space is O(1).

A simple approach for this problem is to one by one pick each node and find
second element whose sum is equal to x in the remaining list by traversing in forward
direction.Time complexity for this problem will be O(n^2) , n is total number of nodes
in doubly linked list.
An efficient solution for this problem is same as this article. Here is the algorithm :
 Initialize two pointer variables to find the candidate elements in the sorted
doubly linked list.Initialize first with start of doubly linked list i.e; first=head and
initialize second with last node of doubly linked list i.e; second=last_node.
 We initialize first and second pointers as first and last nodes. Here we don’t
have random access, so to find second pointer, we traverse the list to initialize
second.
 If current sum of first and second is less than x, then we move first in forward
direction. If current sum of first and second element is greater than x, then we
move second in backward direction.
 Loop termination conditions are also different from arrays. The loop terminates
when either of two pointers become NULL, or they cross each other (second-
>next = first), or they become same (first == second)

// C++ program to find a pair with given sum x.


#include<bits/stdc++.h>
using namespace std;

// structure of node of doubly linked list


struct Node
{
int data;
struct Node *next, *prev;
};

// Function to find pair whose sum equal to given value x.


void pairSum(struct Node *head, int x)
{
// Set two pointers, first to the beginning of DLL
// and second to the end of DLL.
struct Node *first = head;
struct Node *second = head;
while (second->next != NULL)
second = second->next;

// To track if we find a pair or not


bool found = false;

// The loop terminates when either of two pointers


// become NULL, or they cross each other (second->next
// == first), or they become same (first == second)
while (first != NULL && second != NULL &&
first != second && second->next != first)
{
// pair found
if ((first->data + second->data) == x)
{
found = true;
cout << "(" << first->data<< ", "
<< second->data << ")" << endl;

// move first in forward direction


first = first->next;

// move second in backward direction


second = second->prev;
}
else
{
if ((first->data + second->data) < x)
first = first->next;
else
second = second->prev;
}
}

// if pair is not present


if (found == false)
cout << "No pair found";
}

// A utility function to insert a new node at the


// beginning of doubly linked list
void insert(struct Node **head, int data)
{
struct Node *temp = new Node;
temp->data = data;
temp->next = temp->prev = NULL;
if (!(*head))
(*head) = temp;
else
{
temp->next = *head;
(*head)->prev = temp;
(*head) = temp;
}
}
// Driver program
int main()
{
struct Node *head = NULL;
insert(&head, 9);
insert(&head, 8);
insert(&head, 6);
insert(&head, 5);
insert(&head, 4);
insert(&head, 2);
insert(&head, 1);
int x = 7;

pairSum(head, x);

return 0;
}

Output:
(1,6)
(2,5)

Time complexity : O(n)


Auxiliary space : O(1)
If linked list is not sorted, then we can sort the list as a first step. But in that case
overall time complexity would become O(n Log n). We can use Hashing in such
cases if extra space is not a constraint. The hashing based solution is same as
method 2 here.

Insert value in sorted way in a sorted doubly linked


list
Given a sorted doubly linked list and a value to insert, write a function to insert the
value in sorted way.
Initial doubly linked list

Doubly Linked List after insertion of 9


Algorithm:
Let input doubly linked list is sorted in increasing order.
New node passed to the function contains data in the data part and previous and
next link are set to NULL.
sortedInsert(head_ref, newNode)
if (head_ref == NULL)
head_ref = newNode

else if head_ref->data >= newNode->data


newNode->next = head_ref
newNode->next->prev = newNode
head_ref = newNode

else
Initialize current = head_ref
while (current->next != NULL and
current->next->data data)
current = current->next

newNode->next = current->next
if current->next != NULL
newNode->next->prev = newNode

current->next = newNode
newNode->prev = current

// C++ implementation to insert value in sorted way


// in a sorted doubly linked list
#include <bits/stdc++.h>

using namespace std;

// Node of a doubly linked list


struct Node {
int data;
struct Node* prev, *next;
};

// function to create and return a new node


// of a doubly linked list
struct Node* getNode(int data)
{
// allocate node
struct Node* newNode =
(struct Node*)malloc(sizeof(struct Node));

// put in the data


newNode->data = data;
newNode->prev = newNode->next = NULL;
return newNode;
}

// function to insert a new node in sorted way in


// a sorted doubly linked list
void sortedInsert(struct Node** head_ref, struct Node* newNode)
{
struct Node* current;

// if list is empty
if (*head_ref == NULL)
*head_ref = newNode;

// if the node is to be inserted at the beginning


// of the doubly linked list
else if ((*head_ref)->data >= newNode->data) {
newNode->next = *head_ref;
newNode->next->prev = newNode;
*head_ref = newNode;
}

else {
current = *head_ref;

// locate the node after which the new node


// is to be inserted
while (current->next != NULL &&
current->next->data < newNode->data)
current = current->next;

/* Make the appropriate links */


newNode->next = current->next;

// if the new node is not inserted


// at the end of the list
if (current->next != NULL)
newNode->next->prev = newNode;

current->next = newNode;
newNode->prev = current;
}
}

// function to print the doubly linked list


void printList(struct Node* head)
{
while (head != NULL) {
cout << head->data << " ";
head = head->next;
}
}

// Driver program to test above


int main()
{
/* start with the empty doubly linked list */
struct Node* head = NULL;

// insert the following nodes in sorted way


struct Node* new_node = getNode(8);
sortedInsert(&head, new_node);
new_node = getNode(5);
sortedInsert(&head, new_node);
new_node = getNode(3);
sortedInsert(&head, new_node);
new_node = getNode(10);
sortedInsert(&head, new_node);
new_node = getNode(12);
sortedInsert(&head, new_node);
new_node = getNode(9);
sortedInsert(&head, new_node);

cout << "Created Doubly Linked Listn";


printList(head);
return 0;
}

Output:
Created Doubly Linked List
3 5 8 9 10 12
Time Complexity: O(n)

Count triplets in a sorted doubly linked list whose


sum is equal to a given value x
Given a sorted doubly linked list of distinct nodes(no two nodes have the same data)
and a value x. Count triplets in the list that sum up to a given value x.
Examples:

/ C++ implementation to count triplets in a sorted doubly linked list


// whose sum is equal to a given value 'x'
#include <bits/stdc++.h>

using namespace std;

// structure of node of doubly linked list


struct Node {
int data;
struct Node* next, *prev;
};
// function to count triplets in a sorted doubly linked list
// whose sum is equal to a given value 'x'
int countTriplets(struct Node* head, int x)
{
struct Node* ptr1, *ptr2, *ptr3;
int count = 0;

// generate all possible triplets


for (ptr1 = head; ptr1 != NULL; ptr1 = ptr1->next)
for (ptr2 = ptr1->next; ptr2 != NULL; ptr2 = ptr2->next)
for (ptr3 = ptr2->next; ptr3 != NULL; ptr3 = ptr3->next)

// if elements in the current triplet sum up to 'x'


if ((ptr1->data + ptr2->data + ptr3->data) == x)

// increment count
count++;

// required count of triplets


return count;
}

// A utility function to insert a new node at the


// beginning of doubly linked list
void insert(struct Node** head, int data)
{
// allocate node
struct Node* temp = new Node();

// put in the data


temp->data = data;
temp->next = temp->prev = NULL;

if ((*head) == NULL)
(*head) = temp;
else {
temp->next = *head;
(*head)->prev = temp;
(*head) = temp;
}
}

// Driver program to test above


int main()
{
// start with an empty doubly linked list
struct Node* head = NULL;

// insert values in sorted order


insert(&head, 9);
insert(&head, 8);
insert(&head, 6);
insert(&head, 5);
insert(&head, 4);
insert(&head, 2);
insert(&head, 1);
int x = 17;

cout << "Count = "


<< countTriplets(head, x);
return 0;
}

Method 3 Efficient Approach(Use of two pointers):


Traverse the doubly linked list from left to right. For each current node during the
traversal, initailze two pointers first = pointer to the node next to the current node
and last = pointer to the last node of the list. Now, count pairs in the list
from first to last pointer that sum up to value (x – current node’s data)(algorithm
described in this post). Add this count to the total_count of triplets. Pointer to
the last node can be found only once in the beginning.

// C++ implementation to count triplets in a sorted doubly linked list


// whose sum is equal to a given value 'x'
#include <bits/stdc++.h>

using namespace std;

// structure of node of doubly linked list


struct Node {
int data;
struct Node* next, *prev;
};

// function to count pairs whose sum equal to given 'value'


int countPairs(struct Node* first, struct Node* second, int value)
{
int count = 0;

// The loop terminates when either of two pointers


// become NULL, or they cross each other (second->next
// == first), or they become same (first == second)
while (first != NULL && second != NULL &&
first != second && second->next != first) {

// pair found
if ((first->data + second->data) == value) {

// increment count
count++;

// move first in forward direction


first = first->next;

// move second in backward direction


second = second->prev;
}

// if sum is greater than 'value'


// move second in backward direction
else if ((first->data + second->data) > value)
second = second->prev;
// else move first in forward direction
else
first = first->next;
}

// required count of pairs


return count;
}

// function to count triplets in a sorted doubly linked list


// whose sum is equal to a given value 'x'
int countTriplets(struct Node* head, int x)
{
// if list is empty
if (head == NULL)
return 0;

struct Node* current, *first, *last;


int count = 0;

// get pointer to the last node of


// the doubly linked list
last = head;
while (last->next != NULL)
last = last->next;

// traversing the doubly linked list


for (current = head; current != NULL; current = current->next) {

// for each current node


first = current->next;

// count pairs with sum(x - current->data) in the range


// first to last and add it to the 'count' of triplets
count += countPairs(first, last, x - current->data);
}

// required count of triplets


return count;
}

// A utility function to insert a new node at the


// beginning of doubly linked list
void insert(struct Node** head, int data)
{
// allocate node
struct Node* temp = new Node();

// put in the data


temp->data = data;
temp->next = temp->prev = NULL;

if ((*head) == NULL)
(*head) = temp;
else {
temp->next = *head;
(*head)->prev = temp;
(*head) = temp;
}
}

// Driver program to test above


int main()
{
// start with an empty doubly linked list
struct Node* head = NULL;

// insert values in sorted order


insert(&head, 9);
insert(&head, 8);
insert(&head, 6);
insert(&head, 5);
insert(&head, 4);
insert(&head, 2);
insert(&head, 1);

int x = 17;

cout << "Count = "


<< countTriplets(head, x);
return 0;
}
Output:
Count = 2
Time Complexity: O(n2)
Auxiliary Space: O(1)

Remove duplicates from a sorted doubly linked list


Given a sorted doubly linked list containing n nodes. The problem is to remove
duplicate nodes from the given list.
Examples:

Algorithm:
removeDuplicates(head_ref, x)
if head_ref == NULL
return
Initialize current = head_ref
while current->next != NULL
if current->data == current->next->data
deleteNode(head_ref, current->next)
else
current = current->next
The algorithm for deleteNode(head_ref, current) (which deletes the node using the
pointer to the node) is discussed in this post.

/* C++ implementation to remove duplicates from a


sorted 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 remove duplicates from a


sorted doubly linked list */
void removeDuplicates(struct Node** head_ref)
{
/* if list is empty */
if ((*head_ref) == NULL)
return;

struct Node* current = *head_ref;


struct Node* next;

/* traverse the list till the last node */


while (current->next != NULL) {
/* Compare current node with next node */
if (current->data == current->next->data)

/* delete the node pointed to by


'current->next' */
deleteNode(head_ref, current->next);

/* else simply move to the next node */


else
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 begining,


prev is always NULL */
new_node->prev = NULL;

/* link the old list off 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 list is empty */
if (head == NULL)
cout << "Doubly Linked list empty";

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:
4<->4<->4<->4<->6<->8<->8<->10<->12<->12 */
push(&head, 12);
push(&head, 12);
push(&head, 10);
push(&head, 8);
push(&head, 8);
push(&head, 6);
push(&head, 4);
push(&head, 4);
push(&head, 4);
push(&head, 4);

cout << "Original Doubly linked list:n";


printList(head);

/* remove duplicate nodes */


removeDuplicates(&head);

cout << "\nDoubly linked list after"


" removing duplicates:n";
printList(head);

return 0;
}

Output:
Original Doubly linked list:
4 4 4 4 6 8 8 10 12 12
Doubly linked list after removing duplicates:
4 6 8 10 12
Time Complexity: O(n)

Delete all occurrences of a given key in a doubly


linked list
Given a doubly linked list and a key x. The problem is to delete all occurrences of the
given key x from the doubly linked list.
Examples:

Algorithm:
delAllOccurOfGivenKey(head_ref, x)
if head_ref == NULL
return
Initialize current = head_ref
Declare next
while current != NULL
if current->data == x
next = current->next
deleteNode(head_ref, current)
current = next
else
current = current->next
The algorithm for deleteNode(head_ref, current) (which deletes the node using the
pointer to the node) is discussed in this post.

/* C++ implementation to delete all occurrences


of a given key in a 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 all occurrences of the given


key 'x' */
void deleteAllOccurOfX(struct Node** head_ref, int x)
{
/* if list is empty */
if ((*head_ref) == NULL)
return;

struct Node* current = *head_ref;


struct Node* next;

/* traverse the list up to the end */


while (current != NULL) {

/* if node found with the value 'x' */


if (current->data == x) {

/* save current's next node in the


pointer 'next' */
next = current->next;

/* delete the node pointed to by


'current' */
deleteNode(head_ref, current);

/* update current */
current = next;
}

/* else simply move to the next node */


else
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 begining,


prev is always NULL */
new_node->prev = NULL;

/* link the old list off 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 list is empty */
if (head == NULL)
cout << "Doubly Linked list empty";

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:


2<->2<->10<->8<->4<->2<->5<->2 */
push(&head, 2);
push(&head, 5);
push(&head, 2);
push(&head, 4);
push(&head, 8);
push(&head, 10);
push(&head, 2);
push(&head, 2);

cout << "Original Doubly linked list:n";


printList(head);

int x = 2;

/* delete all occurrences of 'x' */


deleteAllOccurOfX(&head, x);

cout << "\nDoubly linked list after deletion of "


<< x << ":n";
printList(head);

return 0;
}

Output:
Original Doubly linked list:
2 2 10 8 4 2 5 2
Doubly linked list after deletion of 2:
10 8 4 5
Time Complexity: O(n)

Reverse a doubly linked list in groups of given size


Given a doubly linked list containing n nodes. The problem is to reverse every group
of k nodes in the list.
Examples:

Approach: Create a recursive function say reverse(head, k). This function receives the
head or the first node of each group of k nodes. It reverses those group of k nodes by
applying the approach discussed in Reverse a doubly linked list | Set-2. After reversing the
group of k nodes the function checks whether next group of nodes exists in the list or not. If
group exists then it makes a recursive call to itself with the first node of the next group and
makes the necessary adjustments with the next and previous links of that group. Finally it
returns the new head node of the reversed group.
// C++ implementation to reverse a doubly linked list
// in groups of given size
#include <bits/stdc++.h>

using namespace std;

// a node of the doubly linked list


struct Node {
int data;
Node *next, *prev;
};

// function to get a new node


Node* getNode(int data)
{
// allocate space
Node* new_node = (Node*)malloc(sizeof(Node));

// put in the data


new_node->data = data;
new_node->next = new_node->prev = NULL;
return new_node;
}

// function to insert a node at the beginging


// of the Doubly Linked List
void push(Node** head_ref, Node* new_node)
{
// since we are adding at the begining,
// prev is always NULL
new_node->prev = NULL;

// link the old list off 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 reverse a doubly linked list


// in groups of given size
Node* revListInGroupOfGivenSize(Node* head, int k)
{
Node *current = head;
Node* next = NULL;
Node* newHead = NULL;
int count = 0;

// reversing the current group of k


// or less than k nodes by adding
// them at the beginning of list
// 'newHead'
while (current != NULL && count < k)
{
next = current->next;
push(&newHead, current);
current = next;
count++;
}

// if next group exists then making the desired


// adjustments in the link
if (next != NULL)
{
head->next = revListInGroupOfGivenSize(next, k);
head->next->prev = head;
}

// pointer to the new head of the


// reversed group
return newHead;
}

// Function to print nodes in a


// given doubly linked list
void printList(Node* head)
{
while (head != NULL) {
cout << head->data << " ";
head = head->next;
}
}

// Driver program to test above


int main()
{
// Start with the empty list
Node* head = NULL;
// Create doubly linked: 10<->8<->4<->2
push(&head, getNode(2));
push(&head, getNode(4));
push(&head, getNode(8));
push(&head, getNode(10));

int k = 2;

cout << "Original list: ";


printList(head);

// Reverse doubly linked list in groups of


// size 'k'
head = revListInGroupOfGivenSize(head, k);

cout << "\nModified list: ";


printList(head);

return 0;
}
Output:
Original list: 10 8 4 2
Modified list: 8 10 2 4
Time Complexity: O(n).

Convert a given Binary Tree to Doubly Linked List |

Given a Binary Tree (BT), convert it to a Doubly Linked List(DLL) In-Place. The left
and right pointers in nodes are to be used as previous and next pointers respectively
in converted DLL. The order of nodes in DLL must be same as Inorder of the given
Binary Tree. The first node of Inorder traversal (left most node in BT) must be head
node of the DLL.

// C++ program to convert a given Binary


// Tree to Doubly Linked List
#include <stdio.h>
#include <stdlib.h>

// Structure for tree and linked list


struct Node
{
int data;
Node *left, *right;
};

// A simple recursive function to convert a given


// Binary tree to Doubly Linked List
// root --> Root of Binary Tree
// head_ref --> Pointer to head node of created
// doubly linked list
void BToDLL(Node* root, Node** head_ref)
{
// Base cases
if (root == NULL)
return;

// Recursively convert right subtree


BToDLL(root->right, head_ref);

// insert root into DLL


root->right = *head_ref;

// Change left pointer of previous head


if (*head_ref != NULL)
(*head_ref)->left = root;

// Change head of Doubly linked list


*head_ref = root;

// Recursively convert left subtree


BToDLL(root->left, head_ref);
}

// Utility function for allocating node for Binary


// Tree.
Node* newNode(int data)
{
Node* node = new Node;
node->data = data;
node->left = node->right = NULL;
return node;
}

// Utility function for printing double linked list.


void printList(Node* head)
{
printf("Extracted Double Linked list is:\n");
while (head)
{
printf("%d ", head->data);
head = head->right;
}
}
// Driver program to test above function
int main()
{
/* Constructing below tree
5
/ \
3 6
/ \ \
1 4 8
/ \ / \
0 2 7 9 */
Node* root = newNode(5);
root->left = newNode(3);
root->right = newNode(6);
root->left->left = newNode(1);
root->left->right = newNode(4);
root->right->right = newNode(8);
root->left->left->left = newNode(0);
root->left->left->right = newNode(2);
root->right->right->left = newNode(7);
root->right->right->right = newNode(9);

Node* head = NULL;


BToDLL(root, &head);

printList(head);

return 0;
}
Output :
Extracted Double Linked list is:
0 1 2 3 4 5 6 7 8 9

Replace even nodes of a doubly linked list with the


elements of array
Given a doubly linked list and an array with only odd values. Both are of equal size
N. The task is replace all node which have even value with the Array elements from
left to right.
Examples:
Input : List = 6 9 8 7 4
Arr[] = {3, 5, 23, 17, 1}
Output : List = 3 9 5 7 23
Input : List = 9 14 7 12 8 13
Arr[] = {5, 1, 17, 21, 11, 7}

Approach: The idea is to traverse the nodes of the doubly linked list one by one and
get the pointer of the nodes having even data then replace by the value of the array
and increment the index of the array and move to the next node in the linked list.
Below is the implementation of above approach:
// C++ implementation to create
// odd doubly linked list
#include <bits/stdc++.h>
using namespace std;

// Node of the doubly linked list


struct Node {
int data;
Node *prev, *next;
};

// function to insert a node at the beginning


// of the Doubly Linked List
void push(Node** head_ref, int new_data)
{
// allocate node
Node* new_node = (Node*)malloc(sizeof(struct Node));

// put in the data


new_node->data = new_data;

// since we are adding at the begining,


// prev is always NULL
new_node->prev = NULL;

// link the old list off 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 make all node is odd


void makeOddNode(Node** head_ref, int A[], int n)
{
Node* ptr = *head_ref;
Node* next;
int i = 0;
// traves list till last node
while (ptr != NULL) {
next = ptr->next;
// check if node is even then
// replace it and incriment in i
if (ptr->data % 2 == 0) {
ptr->data = A[i];
i++;
}
ptr = next;
}
// return sum of nodes which is divided by K
}
// function to print nodes in a
// given doubly linked list
void printList(Node* head)
{
while (head != NULL) {
cout << head->data << " ";
head = head->next;
}
}

// Driver program to test above


int main()
{
// start with the empty list
Node* head = NULL;

// create the doubly linked list


// 6 <=> 9 <=> 8 <=> 7 <=> 4
int Arr[] = { 3, 5, 23, 17, 1 };
push(&head, 4);
push(&head, 7);
push(&head, 8);
push(&head, 9);
push(&head, 6);
int n = sizeof(Arr) / sizeof(Arr[0]);
cout << "Original List: ";
printList(head);
cout << endl;
makeOddNode(&head, Arr, n);
cout << "New odd List: ";
printList(head);
}
Output:
Original List: 6 9 8 7 4
New odd List: 3 9 5 7 23
Time Complexity: O(N), where N is the total number of nodes.

Rotate Doubly linked list by N nodes


Given a doubly linked list, rotate the linked list counter-clockwise by N nodes. Here N
is a given positive integer and is smaller than the count of nodes in linked list.

N=2
Rotated List:

Examples:
Input : a b c d e N = 2
Output : c d e a b

Input : a b c d e f g h N = 4
Output : e f g h a b c d

To rotate the Doubly linked list, we need to change next of Nth node to NULL, next of
last node to previous head node, and prev of head node to last node and finally
change head to (N+1)th node and prev of new head node to NULL (Prev of Head
node in doubly linked list is NULL)
So we need to get hold of three nodes: Nth node, (N+1)th node and last node.
Traverse the list from beginning and stop at Nth node. Store pointer to Nth node. We
can get (N+1)th node using NthNode->next. Keep traversing till end and store
pointer to last node also. Finally, change pointers as stated above and at Last Print
Rotated List using
PrintList Function.

 C++
 Java
 C#
filter_none
edit
play_arrow
brightness_4
// C++ program to rotate a Doubly linked
// list counter clock wise by N times
#include <bits/stdc++.h>
using namespace std;

/* Link list node */


struct Node {
char data;
struct Node* prev;
struct Node* next;
};

// This function rotates a doubly linked


// list counter-clockwise and updates the
// head. The function assumes that N is
// smallerthan size of linked list. It
// doesn't modify the list if N is greater
// than or equal to size
void rotate(struct Node** head_ref, int N)
{
if (N == 0)
return;

// Let us understand the below code


// for example N = 2 and
// list = a <-> b <-> c <-> d <-> e.
struct Node* current = *head_ref;

// current will either point to Nth


// or NULL after this loop. Current
// will point to node 'b' in the
// above example
int count = 1;
while (count < N && current != NULL) {
current = current->next;
count++;
}

// If current is NULL, N is greater


// than or equal to count of nodes
// in linked list. Don't change the
// list in this case
if (current == NULL)
return;

// current points to Nth node. Store


// it in a variable. NthNode points to
// node 'b' in the above example
struct Node* NthNode = current;

// current will point to last node


// after this loop current will point
// to node 'e' in the above example
while (current->next != NULL)
current = current->next;
// Change next of last node to previous
// head. Next of 'e' is now changed to
// node 'a'
current->next = *head_ref;

// Change prev of Head node to current


// Prev of 'a' is now changed to node 'e'
(*head_ref)->prev = current;

// Change head to (N+1)th node


// head is now changed to node 'c'
*head_ref = NthNode->next;

// Change prev of New Head node to NULL


// Because Prev of Head Node in Doubly
// linked list is NULL
(*head_ref)->prev = NULL;

// change next of Nth node to NULL


// next of 'b' is now NULL
NthNode->next = NULL;
}

// Function to insert a node at the


// beginning of the Doubly Linked List
void push(struct Node** head_ref, int new_data)
{
struct Node* new_node = new Node;
new_node->data = new_data;
new_node->prev = NULL;
new_node->next = (*head_ref);
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
*head_ref = new_node;
}

/* Function to print linked list */


void printList(struct Node* node)
{
while (node->next != NULL) {
cout << node->data << " "
<< "<=>"
<< " ";
node = node->next;
}
cout << node->data;
}

// Driver's Code
int main(void)
{
/* Start with the empty list */
struct Node* head = NULL;

/* Let us create the doubly


linked list a<->b<->c<->d<->e */
push(&head, 'e');
push(&head, 'd');
push(&head, 'c');
push(&head, 'b');
push(&head, 'a');

int N = 2;

cout << "Given linked list \n";


printList(head);
rotate(&head, N);

cout << "\nRotated Linked list \n";


printList(head);

return 0;
}
Output:
Given linked list
a b c d e
Rotated Linked list
c d e a b

Delete all the nodes from a doubly linked list that are
smaller than a given value
Given a doubly linked list containing N nodes and a number K, the task is to delete
all the nodes from the list that are smaller than the given value K.
Examples:
Input: 15 <=> 16 <=> 10 <=> 9 <=> 6 <=> 7 <=> 17
K = 10
Output: 15 <=> 16 <=> 10 <=> 17

Input: 5 <=> 3 <=> 6 <=> 8 <=> 4 <=> 1 <=> 2 <=> 9


K = 4
Output: 5 <=> 6 <=> 8 <=> 4 <=> 9

Approach: Traverse the nodes of the doubly linked list one by one and get the
pointer of the nodes having data value smaller than K. Refer to the article
on Deleting a node from Doubly Linked List to delete a node.
Below is the implementation of the above approach:
// C++ implementation to delete all
// the nodes from the doubly
// linked list that are smaller than
// the specified value K
#include <bits/stdc++.h>

using namespace std;


// Node of the doubly linked list
struct Node {
int data;
Node *prev, *next;
};

// function to insert a node at the beginning


// of the Doubly Linked List
void push(Node** head_ref, int new_data)
{
// allocate node
Node* new_node = (Node*)malloc(sizeof(struct Node));

// put in the data


new_node->data = new_data;

// since we are adding at the begining,


// prev is always NULL
new_node->prev = NULL;

// link the old list off 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 delete a node in a Doubly Linked List.


// head_ref --> pointer to head node pointer.
// del --> pointer to node to be deleted
void deleteNode(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


free(del);

return;
}

// function to delete all the nodes


// from the doubly linked
// list that are smaller than the
// specified value K
void deletesmallerNodes(Node** head_ref, int K)
{
Node* ptr = *head_ref;
Node* next;

while (ptr != NULL) {


next = ptr->next;
// if true, delete node 'ptr'
if (ptr->data < K)
deleteNode(head_ref, ptr);
ptr = next;
}
}

// function to print nodes in a


// given doubly linked list
void printList(Node* head)
{
while (head != NULL) {
cout << head->data << " ";
head = head->next;
}
}

// Driver program to test above


int main()
{
// start with the empty list
Node* head = NULL;

// create the doubly linked list


// 15 <-> 16 <-> 10 <-> 9 <-> 6 <-> 7 <-> 17
push(&head, 17);
push(&head, 7);
push(&head, 6);
push(&head, 9);
push(&head, 10);
push(&head, 16);
push(&head, 15);

int K = 10;

cout << "Original List: ";


printList(head);

deletesmallerNodes(&head, K);

cout << "\nModified List: ";


printList(head);
}

Output:
Original List: 15 16 10 9 6 7 17
Modified List: 15 16 10 17
Time Complexity: O(N), where N is the total number of Nodes.

Delete N nodes after M nodes of a linked list


Given a linked list and two integers M and N. Traverse the linked list such that you
retain M nodes then delete next N nodes, continue the same till end of the linked list.
Difficulty Level: Rookie
Examples:
Input:
M = 2, N = 2
Linked List: 1->2->3->4->5->6->7->8
Output:
Linked List: 1->2->5->6

Input:
M = 3, N = 2
Linked List: 1->2->3->4->5->6->7->8->9->10
Output:
Linked List: 1->2->3->6->7->8

Input:
M = 1, N = 1
Linked List: 1->2->3->4->5->6->7->8->9->10
Output:
Linked List: 1->3->5->7->9

The main part of the problem is to maintain proper links between nodes, make sure
that all corner cases are handled. Following is C implementation of function
skipMdeleteN() that skips M nodes and delete N nodes till end of list. It is assumed
that M cannot be 0.

// C++ program to delete N nodes

// after M nodes of a linked list


#include <bits/stdc++.h>

using namespace std;

// A linked list node

class Node

public:

int data;

Node *next;

};

/* Function to insert a node at the beginning */

void push(Node ** head_ref, int new_data)

/* allocate node */

Node* new_node = new Node();

/* put in the data */

new_node->data = new_data;

/* link the old list off the new node */

new_node->next = (*head_ref);

/* move the head to point to the new node */

(*head_ref) = new_node;

/* Function to print linked list */

void printList(Node *head)

Node *temp = head;

while (temp != NULL)

{
cout<<temp->data<<" ";

temp = temp->next;

cout<<endl;

// Function to skip M nodes and then

// delete N nodes of the linked list.

void skipMdeleteN(Node *head, int M, int N)

Node *curr = head, *t;

int count;

// The main loop that traverses

// through the whole list

while (curr)

// Skip M nodes

for (count = 1; count < M &&

curr!= NULL; count++)

curr = curr->next;

// If we reached end of list, then return

if (curr == NULL)

return;

// Start from next node and delete N nodes

t = curr->next;

for (count = 1; count<=N && t!= NULL; count++)

Node *temp = t;

t = t->next;

free(temp);

}
// Link the previous list with remaining nodes

curr->next = t;

// Set current pointer for next iteration

curr = t;

// Driver code

int main()

/* Create following linked list

1->2->3->4->5->6->7->8->9->10 */

Node* head = NULL;

int M=2, N=3;

push(&head, 10);

push(&head, 9);

push(&head, 8);

push(&head, 7);

push(&head, 6);

push(&head, 5);

push(&head, 4);

push(&head, 3);

push(&head, 2);

push(&head, 1);

cout << "M = " << M<< " N = " << N << "\nGiven Linked list is :\n";

printList(head);

skipMdeleteN(head, M, N);

cout<<"\nLinked list after deletion is :\n";


printList(head);

return 0;

// This code is contributed by rathbhupendra

Output:
M = 2, N = 3
Given Linked list is :
1 2 3 4 5 6 7 8 9 10

Linked list after deletion is :


1 2 6 7

Check if a doubly linked list of characters is


palindrome or not
Given a doubly linked list of characters, write a function that returns true if the given
doubly linked list is palindrome, else false.

1. Create a doubly linked list where each node contains only one character of a
string.
2. Initialize two pointers left at starting of list and right at the end of the list.
3. Check the data at left node is equal to right node, if it is equal then increment
left and decrement right till middle of the list, if at any stage it is not equal then
return false.

// C++ program to check if doubly


// linked list is palindrome or not
#include<bits/stdc++.h>
using namespace std;

// Structure of node
struct Node
{
char data;
struct Node *next;
struct Node *prev;
};

/* Given a reference (pointer to pointer) to


the head of a list and an int, inserts a
new node on the front of the list. */
void push(struct Node** head_ref, char new_data)
{
struct Node* new_node = new Node;
new_node->data = new_data;
new_node->next = (*head_ref);
new_node->prev = NULL;
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node ;
(*head_ref) = new_node;
}

// Function to check if list is palindrome or not


bool isPalindrome(struct Node *left)
{
if (left == NULL)
return true;

// Find rightmost node


struct Node *right = left;
while (right->next != NULL)
right = right->next;

while (left != right)


{
if (left->data != right->data)
return false;

left = left->next;
right = right->prev;
}

return true;
}

// Driver program
int main()
{
struct Node* head = NULL;
push(&head, 'l');
push(&head, 'e');
push(&head, 'v');
push(&head, 'e');
push(&head, 'l');

if (isPalindrome(head))
printf("It is Palindrome");
else
printf("Not Palindrome");

return 0;
}
Output:
It is Palindrome
Time complexity: O(n)
Auxiliary Space : O(1)

Delete all the even nodes from a Doubly Linked List


Given a doubly linked list containing N nodes, the task is to delete all the even nodes
from the list.

Examples:
Input: Initial List = 15 <=> 16 <=> 6 <=> 7 <=> 17
Output: Final List = 15 <=> 7 <=> 17
Input: Initial List = 5 <=> 3 <=> 6 <=> 8 <=> 4 <=> 1 <=> 2 <=> 9
Output: Final List = 5 <=> 3 <=> 1 <=> 9

// C++ implementation to delete all


// the even nodes from the doubly
// linked list
#include <bits/stdc++.h>

using namespace std;

// Node of the doubly linked list


struct Node {
int data;
Node *prev, *next;
};

// function to insert a node at the beginning


// of the Doubly Linked List
void push(Node** head_ref, int new_data)
{
// allocate node
Node* new_node = (Node*)malloc(sizeof(struct Node));

// put in the data


new_node->data = new_data;

// since we are adding at the begining,


// prev is always NULL
new_node->prev = NULL;

// link the old list off 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 delete a node in a Doubly Linked List.


// head_ref --> pointer to head node pointer.
// del --> pointer to node to be deleted
void deleteNode(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


free(del);

return;
}

// function to delete all the even nodes


// from the doubly linked list
void deleteEvenNodes(Node** head_ref)
{
Node* ptr = *head_ref;
Node* next;

while (ptr != NULL) {


next = ptr->next;
// if true, delete node 'ptr'
if (ptr->data % 2 == 0)
deleteNode(head_ref, ptr);
ptr = next;
}
}
// function to print nodes in a
// given doubly linked list
void printList(Node* head)
{
while (head != NULL) {
cout << head->data << " ";
head = head->next;
}
}

// Driver program
int main()
{
// start with the empty list
Node* head = NULL;

// create the doubly linked list


// 15 <-> 16 <-> 7 <-> 6 <-> 17
push(&head, 17);
push(&head, 6);
push(&head, 7);
push(&head, 16);
push(&head, 15);

cout << "Original List: ";


printList(head);

deleteEvenNodes(&head);

cout << "\nModified List: ";


printList(head);
}
Output:
Original List: 15 16 7 6 17
Modified List: 15 7 17
Time Complexity: O(N), where N is the total number of nodes.

Extract Leaves of a Binary Tree in a Doubly Linked


List
Given a Binary Tree, extract all leaves of it in a Doubly Linked List (DLL). Note that
the DLL need to be created in-place. Assume that the node structure of DLL and
Binary Tree is same, only the meaning of left and right pointers are different. In DLL,
left means previous pointer and right means next pointer.
Let the following be input binary tree
1
/ \
2 3
/ \ \
4 5 6
/ \ / \
7 8 9 10

Output:
Doubly Linked List
785910

Modified Tree:
1
/ \
2 3
/ \
4 6
We need to traverse all leaves and connect them by changing their left and right
pointers. We also need to remove them from Binary Tree by changing left or right pointers in
parent nodes. There can be many ways to solve this. In the following implementation, we
add leaves at the beginning of current linked list and update head of the list using pointer to
head pointer. Since we insert at the beginning, we need to process leaves in reverse order.
For reverse order, we first traverse the right subtree then the left subtree. We use return
values to update left or right pointers in parent nodes.

// C++ program to extract leaves of


// a Binary Tree in a Doubly Linked List
#include <bits/stdc++.h>
using namespace std;

// Structure for tree and linked list


class Node
{
public:
int data;
Node *left, *right;
};

// Main function which extracts all


// leaves from given Binary Tree.
// The function returns new root of
// Binary Tree (Note that root may change
// if Binary Tree has only one node).
// The function also sets *head_ref as
// head of doubly linked list. left pointer
// of tree is used as prev in DLL
// and right pointer is used as next
Node* extractLeafList(Node *root, Node **head_ref)
{
// Base cases
if (root == NULL) return NULL;

if (root->left == NULL && root->right == NULL)


{
// This node is going to be added
// to doubly linked list of leaves,
// set right pointer of this node
// as previous head of DLL. We
// don't need to set left pointer
// as left is already NULL
root->right = *head_ref;

// Change left pointer of previous head


if (*head_ref != NULL) (*head_ref)->left = root;

// Change head of linked list


*head_ref = root;

return NULL; // Return new root


}

// Recur for right and left subtrees


root->right = extractLeafList(root->right, head_ref);
root->left = extractLeafList(root->left, head_ref);

return root;
}

// Utility function for allocating node for Binary Tree.


Node* newNode(int data)
{
Node* node = new Node();
node->data = data;
node->left = node->right = NULL;
return node;
}

// Utility function for printing tree in In-Order.


void print(Node *root)
{
if (root != NULL)
{
print(root->left);
cout<<root->data<<" ";
print(root->right);
}
}

// Utility function for printing double linked list.


void printList(Node *head)
{
while (head)
{
cout<<head->data<<" ";
head = head->right;
}
}

// Driver code
int main()
{
Node *head = NULL;
Node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
root->right->right = newNode(6);
root->left->left->left = newNode(7);
root->left->left->right = newNode(8);
root->right->right->left = newNode(9);
root->right->right->right = newNode(10);

cout << "Inorder Trvaersal of given Tree is:\n";


print(root);

root = extractLeafList(root, &head);

cout << "\nExtracted Double Linked list is:\n";


printList(head);

cout << "\nInorder traversal of modified tree is:\n";


print(root);
return 0;
}

// This code is contributed by rathbhupendra

Output:
Inorder Trvaersal of given Tree is:
7 4 8 2 5 1 3 9 6 10
Extracted Double Linked list is:
7 8 5 9 10
Inorder traversal of modified tree is:
4 2 1 3 6
Time Complexity: O(n), the solution does a single traversal of given Binary Tree.
Sort a k sorted doubly linked list
Given a doubly linked list containing n nodes, where each node is at most k away
from its target position in the list. The problem is to sort the given doubly linked list.
For example, let us consider k is 2, a node at position 7 in the sorted doubly linked
list, can be at positions 5, 6, 7, 8, 9 in the given doubly linked list.
Examples:

Naive Approach: Sort the given doubly linked list using insertion sort technique.
Time Complexity: O(nk)
Auxiliary Space: O(1)
Efficient Approach: We can sort the list using the MIN HEAP data structure. The
approach has been explained in Sort a nearly sorted (or K sorted) array. We only
have to be careful while traversing the input doubly linked list and adjusting the
required next and previous links in the final sorted list.
filter_none
edit
play_arrow
brightness_5
// C++ implementation to sort a k sorted 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;

};

// 'compare' function used to build up the

// priority queue
struct compare {

bool operator()(struct Node* p1, struct Node* p2)

return p1->data > p2->data;

};

// function to sort a k sorted doubly linked list

struct Node* sortAKSortedDLL(struct Node* head, int k)

// if list is empty

if (head == NULL)

return head;

// priority_queue 'pq' implemeted as min heap with the

// help of 'compare' function

priority_queue<Node*, vector<Node*>, compare> pq;

struct Node* newHead = NULL, *last;

// Create a Min Heap of first (k+1) elements from

// input doubly linked list

for (int i = 0; head != NULL && i <= k; i++) {

// push the node on to 'pq'

pq.push(head);

// move to the next node

head = head->next;

// loop till there are elements in 'pq'

while (!pq.empty()) {
// place root or top of 'pq' at the end of the

// result sorted list so far having the first node

// pointed to by 'newHead'

// and adjust the required links

if (newHead == NULL) {

newHead = pq.top();

newHead->prev = NULL;

// 'last' points to the last node

// of the result sorted list so far

last = newHead;

else {

last->next = pq.top();

pq.top()->prev = last;

last = pq.top();

// remove element from 'pq'

pq.pop();

// if there are more nodes left in the input list

if (head != NULL) {

// push the node on to 'pq'

pq.push(head);

// move to the next node

head = head->next;

// making 'next' of last node point to NULL


last->next = NULL;

// new head of the required sorted DLL

return newHead;

// 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 begining,

// prev is always NULL

new_node->prev = NULL;

// link the old list off 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 list is empty

if (head == NULL)

cout << "Doubly Linked list empty";

while (head != NULL) {

cout << head->data << " ";

head = head->next;

// Driver program to test above

int main()

struct Node* head = NULL;

// Create the doubly linked list:

// 3<->6<->2<->12<->56<->8

push(&head, 8);

push(&head, 56);

push(&head, 12);

push(&head, 2);

push(&head, 6);

push(&head, 3);

int k = 2;

cout << "Original Doubly linked list:n";

printList(head);

// sort the biotonic DLL

head = sortAKSortedDLL(head, k);


cout << "\nDoubly linked list after sorting:n";

printList(head);

return 0;

Output:
Original Doubly linked list:
3 6 2 12 56 8
Doubly linked list after sorting:
2 3 6 8 12 56
Time Complexity: O(nLogk)
Auxiliary Space: O(k)

Remove duplicates from an unsorted doubly linked


list
Given an unsorted doubly linked list containing n nodes. The problem is to remove
duplicate nodes from the given list.
Examples:

Method 1 (Naive Approach):


This is the simplest way where two loops are used. Outer loop is used to pick the
elements one by one and inner loop compares the picked element with rest of the
elements.

// C++ implementation to remove duplicates from an

// unsorted 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 remove duplicates from


// an unsorted doubly linked list

void removeDuplicates(struct Node** head_ref)

// if DLL is empty or if it contains only

// a single node

if ((*head_ref) == NULL ||

(*head_ref)->next == NULL)

return;

struct Node* ptr1, *ptr2;

// pick elements one by one

for (ptr1 = *head_ref; ptr1 != NULL; ptr1 = ptr1->next) {

ptr2 = ptr1->next;

// Compare the picked element with the

// rest of the elements

while (ptr2 != NULL) {

// if duplicate, then delete it

if (ptr1->data == ptr2->data) {

// store pointer to the node next to 'ptr2'

struct Node* next = ptr2->next;

// delete node pointed to by 'ptr2'

deleteNode(head_ref, ptr2);

// update 'ptr2'

ptr2 = next;

// else simply move to the next node


else

ptr2 = ptr2->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 begining,

// prev is always NULL

new_node->prev = NULL;

// link the old list off 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 list is empty

if (head == NULL)

cout << "Doubly Linked list empty";

while (head != NULL) {

cout << head->data << " ";

head = head->next;

// Driver program to test above

int main()

struct Node* head = NULL;

// Create the doubly linked list:

// 8<->4<->4<->6<->4<->8<->4<->10<->12<->12

push(&head, 12);

push(&head, 12);

push(&head, 10);

push(&head, 4);

push(&head, 8);

push(&head, 4);

push(&head, 6);

push(&head, 4);

push(&head, 4);

push(&head, 8);

cout << "Original Doubly linked list:n";

printList(head);
/* remove duplicate nodes */

removeDuplicates(&head);

cout << "\nDoubly linked list after "

"removing duplicates:n";

printList(head);

return 0;

Output:
Original Doubly linked list:
8 4 4 6 4 8 4 10 12 12
Doubly linked list after removing duplicates:
8 4 6 10 12
Time Complexity: O(n2)
Auxiliary Space: O(1)
Method 2 (Sorting): Following are the steps:
1. Sort the elements of the doubly linked list using Merge Sort. Refer this post.
2. Remove duplicates in linear time using the algorithm to remove duplicates from a
sorted doubly linked list.
Time Complexity: O(nLogn)
Auxiliary Space: O(1)
Note that this method doesn’t preserve the original order of elements.
Method 3 Efficient Approach(Hashing):
We traverse the doubly linked list from head to end. For every newly encountered
element, we check whether it is in the hash table: if yes, we remove it; otherwise we
put it in the hash table. Hash table is implemented using unordered_set in C++.

// C++ implementation to remove duplicates from an

// unsorted 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 remove duplicates from


// an unsorted doubly linked list

void removeDuplicates(struct Node** head_ref)

// if doubly linked list is empty

if ((*head_ref) == NULL)

return;

// unordered_set 'us' implemented as hash table

unordered_set<int> us;

struct Node* current = *head_ref, *next;

// traverse up to the end of the list

while (current != NULL) {

// if current data is seen before

if (us.find(current->data) != us.end()) {

// store pointer to the node next to

// 'current' node

next = current->next;

// delete the node pointed to by 'current'

deleteNode(head_ref, current);

// update 'current'

current = next;

else {

// insert the current data in 'us'

us.insert(current->data);
// move to the next node

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 off 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 list is empty

if (head == NULL)

cout << "Doubly Linked list empty";

while (head != NULL) {

cout << head->data << " ";

head = head->next;

// Driver program to test above

int main()

struct Node* head = NULL;

// Create the doubly linked list:

// 8<->4<->4<->6<->4<->8<->4<->10<->12<->12

push(&head, 12);

push(&head, 12);

push(&head, 10);

push(&head, 4);

push(&head, 8);

push(&head, 4);

push(&head, 6);

push(&head, 4);

push(&head, 4);

push(&head, 8);

cout << "Original Doubly linked list:n";

printList(head);
/* remove duplicate nodes */

removeDuplicates(&head);

cout << "\nDoubly linked list after "

"removing duplicates:n";

printList(head);

return 0;

Output:
Original Doubly linked list:
8 4 4 6 4 8 4 10 12 12
Doubly linked list after removing duplicates:
8 4 6 10 12
Time Complexity: O(n)
Auxiliary Space: O(n)

You might also like