Sort a k sorted doubly linked list
Last Updated :
14 Mar, 2023
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 the insertion sort technique. While inserting each element in the sorted part of the list, there will be at most k swaps to place the element to its correct position since it is at most k steps away from its correct position.
C++
#include<bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* next;
struct Node* prev;
};
struct Node* sortAKSortedDLL( struct Node* head, int k)
{
if (head == NULL || head->next == NULL)
return head;
for (Node *i = head->next; i != NULL; i = i->next) {
Node *j = i;
while (j->prev != NULL && j->data < j->prev->data) {
Node* temp = j->prev->prev;
Node* temp2 = j->prev;
Node *temp3 = j->next;
j->prev->next = temp3;
j->prev->prev = j;
j->prev = temp;
j->next = temp2;
if (temp != NULL)
temp->next = j;
if (temp3 != NULL)
temp3->prev = temp2;
}
if (j->prev == NULL)
head = j;
}
return head;
}
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->prev = NULL;
new_node->next = (*head_ref);
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
(*head_ref) = new_node;
}
void printList( struct Node* head)
{
if (head == NULL)
cout << "Doubly Linked list empty" ;
while (head != NULL) {
cout << head->data << " " ;
head = head->next;
}
}
int main()
{
struct Node* head = NULL;
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);
head = sortAKSortedDLL(head, k);
cout << "\nDoubly Linked List after sorting:\n" ;
printList(head);
return 0;
}
|
Java
import java.util.*;
class DoublyLinkedList
{
static Node head;
static class Node
{
int data;
Node next, prev;
Node( int d)
{
data = d;
next = prev = null ;
}
}
Node sortAKSortedDLL( Node head, int k) {
if (head == null || head.next == null )
return head;
for (Node i = head.next; i != null ; i = i.next) {
Node j = i;
while (j.prev != null && j.data < j.prev.data) {
Node temp = j.prev.prev;
Node temp2 = j.prev;
Node temp3 = j.next;
j.prev.next = temp3;
j.prev.prev = j;
j.prev = temp;
j.next = temp2;
if (temp != null )
temp.next = j;
if (temp3 != null )
temp3.prev = temp2;
}
if (j.prev == null )
head = j;
}
return head;
}
void push( int new_data)
{
Node new_node = new Node(new_data);
new_node.prev = null ;
new_node.next = head;
if (head != null )
{
head.prev = new_node;
}
head = new_node;
}
void printList(Node node)
{
while (node != null )
{
System.out.print(node.data + " " );
node = node.next;
}
}
public static void main(String[] args)
{
DoublyLinkedList list = new DoublyLinkedList();
list.push( 8 );
list.push( 56 );
list.push( 12 );
list.push( 2 );
list.push( 6 );
list.push( 3 );
int k = 2 ;
System.out.println( "Original Doubly linked list:" );
list.printList(head);
Node sortedDLL = list.sortAKSortedDLL(head, k);
System.out.println( "" );
System.out.println( "Doubly Linked List after sorting:" );
list.printList(sortedDLL);
}
}
|
Python3
head = None
class Node:
def __init__( self , val):
self .data = val
self .prev = None
self . next = None
def sortAKSortedDLL(head , k):
if (head = = None or head. next = = None ):
return head
i = head. next
while (i ! = None ):
j = i
while (j.prev ! = None and j.data < j.prev.data):
temp = j.prev.prev
temp2 = j.prev
temp3 = j. next
j.prev. next = temp3
j.prev.prev = j
j.prev = temp
j. next = temp2
if (temp ! = None ):
temp. next = j
if (temp3 ! = None ):
temp3.prev = temp2
if (j.prev = = None ):
head = j
i = i. next
return head
def push(new_data):
global head
new_node = Node(new_data)
new_node.prev = None
new_node. next = head
if (head ! = None ):
head.prev = new_node
head = new_node
def printList(node):
while (node ! = None ):
print (node.data,end = " " )
node = node. next
push( 8 )
push( 56 )
push( 12 )
push( 2 )
push( 6 )
push( 3 )
k = 2
print ( "Original Doubly linked list:" )
printList(head)
sortedDLL = sortAKSortedDLL(head, k)
print ("")
print ( "Doubly Linked List after sorting:" )
printList(sortedDLL)
|
C#
using System;
class DoublyLinkedList {
static Node head;
public class Node {
public int data;
public Node next, prev;
public Node( int d)
{
data = d;
next = prev = null ;
}
}
public Node sortAKSortedDLL(Node head, int k)
{
if (head == null || head.next == null )
return head;
for (Node i = head.next; i != null ; i = i.next) {
Node j = i;
while (j.prev != null && j.data < j.prev.data)
{
Node temp = j.prev.prev;
Node temp2 = j.prev;
Node temp3 = j.next;
j.prev.next = temp3;
j.prev.prev = j;
j.prev = temp;
j.next = temp2;
if (temp != null )
temp.next = j;
if (temp3 != null )
temp3.prev = temp2;
}
if (j.prev == null )
head = j;
}
return head;
}
public void push( int new_data)
{
Node new_node = new Node(new_data);
new_node.prev = null ;
new_node.next = head;
if (head != null ) {
head.prev = new_node;
}
head = new_node;
}
public void printList(Node node)
{
while (node != null ) {
Console.Write(node.data + " " );
node = node.next;
}
}
public static void Main( string [] args)
{
DoublyLinkedList list = new DoublyLinkedList();
list.push(8);
list.push(56);
list.push(12);
list.push(2);
list.push(6);
list.push(3);
int k = 2;
Console.WriteLine( "Original Doubly linked list:" );
list.printList(head);
Node sortedDLL = list.sortAKSortedDLL(head, k);
Console.WriteLine();
Console.WriteLine(
"Doubly Linked List after sorting:" );
list.printList(sortedDLL);
}
}
|
Javascript
<script>
var head;
class Node {
constructor(val) {
this .data = val;
this .prev = null ;
this .next = null ;
}
}
function sortAKSortedDLL(head , k) {
if (head == null || head.next == null )
return head;
for (i = head.next; i != null ; i = i.next) {
var j = i;
while (j.prev != null && j.data < j.prev.data) {
var temp = j.prev.prev;
var temp2 = j.prev;
var temp3 = j.next;
j.prev.next = temp3;
j.prev.prev = j;
j.prev = temp;
j.next = temp2;
if (temp != null )
temp.next = j;
if (temp3 != null )
temp3.prev = temp2;
}
if (j.prev == null )
head = j;
}
return head;
}
function push(new_data) {
var new_node = new Node(new_data);
new_node.prev = null ;
new_node.next = head;
if (head != null ) {
head.prev = new_node;
}
head = new_node;
}
function printList(node) {
while (node != null ) {
document.write(node.data + " " );
node = node.next;
}
}
push(8);
push(56);
push(12);
push(2);
push(6);
push(3);
var k = 2;
document.write( "Original Doubly linked list:<br/>" );
printList(head);
var sortedDLL = sortAKSortedDLL(head, k);
document.write( "" );
document.write( "<br/>Doubly Linked List after sorting:<br/>" );
printList(sortedDLL);
</script>
|
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(n*k)
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.
Implementation:
CPP
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* next;
struct Node* prev;
};
struct compare {
bool operator()( struct Node* p1, struct Node* p2)
{
return p1->data > p2->data;
}
};
struct Node* sortAKSortedDLL( struct Node* head, int k)
{
if (head == NULL)
return head;
priority_queue<Node*, vector<Node*>, compare> pq;
struct Node* newHead = NULL, *last;
for ( int i = 0; head != NULL && i <= k; i++) {
pq.push(head);
head = head->next;
}
while (!pq.empty()) {
if (newHead == NULL) {
newHead = pq.top();
newHead->prev = NULL;
last = newHead;
}
else {
last->next = pq.top();
pq.top()->prev = last;
last = pq.top();
}
pq.pop();
if (head != NULL) {
pq.push(head);
head = head->next;
}
}
last->next = NULL;
return newHead;
}
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->prev = NULL;
new_node->next = (*head_ref);
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
(*head_ref) = new_node;
}
void printList( struct Node* head)
{
if (head == NULL)
cout << "Doubly Linked list empty" ;
while (head != NULL) {
cout << head->data << " " ;
head = head->next;
}
}
int main()
{
struct Node* head = NULL;
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);
head = sortAKSortedDLL(head, k);
cout << "\nDoubly Linked List after sorting:\n" ;
printList(head);
return 0;
}
|
Java
import java.util.*;
class DoublyLinkedList
{
static Node head;
static class Node
{
int data;
Node next, prev;
Node( int d)
{
data = d;
next = prev = null ;
}
}
class compareNode implements Comparator<Node>
{
public int compare(Node n1, Node n2){
return n1.data-n2.data;
}
}
Node sortAKSortedDLL( Node head, int k)
{
if (head == null )
return head;
PriorityQueue<Node> pq = new PriorityQueue<Node>( new compareNode());
Node newHead = null , last = null ;
for ( int i = 0 ; head != null && i <= k; i++)
{
pq.add(head);
head = head.next;
}
while (!pq.isEmpty())
{
if (newHead == null )
{
newHead = pq.peek();
newHead.prev = null ;
last = newHead;
}
else
{
last.next = pq.peek();
pq.peek().prev = last;
last = pq.peek();
}
pq.poll();
if (head != null )
{
pq.add(head);
head = head.next;
}
}
last.next = null ;
return newHead;
}
void push( int new_data)
{
Node new_node = new Node(new_data);
new_node.prev = null ;
new_node.next = head;
if (head != null )
{
head.prev = new_node;
}
head = new_node;
}
void printList(Node node)
{
while (node != null )
{
System.out.print(node.data + " " );
node = node.next;
}
}
public static void main(String[] args)
{
DoublyLinkedList list = new DoublyLinkedList();
list.push( 8 );
list.push( 56 );
list.push( 12 );
list.push( 2 );
list.push( 6 );
list.push( 3 );
int k = 2 ;
System.out.println( "Original Doubly linked list:" );
list.printList(head);
Node sortedDLL = list.sortAKSortedDLL(head, k);
System.out.println( "" );
System.out.println( "Doubly Linked List after sorting:" );
list.printList(sortedDLL);
}
}
|
Python3
import heapq
head = None
class Node:
def __init__( self , data):
self .data = data
self . next = None
self .prev = None
def sortAKSortedDLL(head, k):
if head = = None :
return head
pq = []
newHead = None
last = None
for i in range (k + 1 ):
heapq.heappush(pq, (head.data, head))
head = head. next
while len (pq) > 0 :
if newHead = = None :
newHead = heapq.heappop(pq)[ 1 ]
newHead.prev = None
last = newHead
else :
last. next = heapq.heappop(pq)[ 1 ]
last. next .prev = last
last = last. next
if head ! = None :
heapq.heappush(pq, (head.data, head))
head = head. next
last. next = None
return newHead
def push(new_data):
global head
new_node = Node(new_data)
new_node.prev = None
new_node. next = head
if (head ! = None ):
head.prev = new_node
head = new_node
def printList(head):
if head is None :
print ( "Doubly Linked list empty" )
while head is not None :
print (head.data, end = " " )
head = head. next
if __name__ = = '__main__' :
push( 8 )
push( 56 )
push( 12 )
push( 2 )
push( 6 )
push( 3 )
k = 2
print ( "Original Doubly linked list:" )
printList(head)
sortedDLL = sortAKSortedDLL(head, k)
print ( "\nDoubly Linked List after sorting:" )
printList(sortedDLL)
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
class Node
{
public int data;
public Node next, prev;
public Node( int d)
{
data = d;
next = prev = null ;
}
}
class DoublyLinkedList
{
public Node head;
public Node sortAKSortedDLL(Node head, int k)
{
if (head == null )
return head;
List<Node> pq = new List<Node>();
Node newHead = null , last = null ;
for ( int i = 0; head != null && i <= k; i++)
{
pq.Add(head);
pq.Sort( delegate (Node x, Node y){
return x.data.CompareTo(y.data);
});
head = head.next;
}
while (pq.Count > 0)
{
if (newHead == null )
{
newHead = pq[0];
newHead.prev = null ;
last = newHead;
}
else
{
last.next = pq[0];
pq[0].prev = last;
last = pq[0];
}
pq.RemoveAt(0);
if (head != null )
{
pq.Add(head);
pq.Sort( delegate (Node x, Node y){
return x.data.CompareTo(y.data);
});
head = head.next;
}
}
last.next = null ;
return newHead;
}
public Node push( int new_data)
{
Node new_node = new Node(new_data);
new_node.prev = null ;
new_node.next = head;
if (head != null )
{
head.prev = new_node;
}
head = new_node;
return head;
}
public void printList(Node node)
{
while (node != null )
{
Console.Write(node.data + " " );
node = node.next;
}
}
}
class HelloWorld {
static void Main() {
DoublyLinkedList list = new DoublyLinkedList();
Node head = list.push(8);
head = list.push(56);
head = list.push(12);
head = list.push(2);
head = list.push(6);
head = list.push(3);
int k = 2;
Console.WriteLine( "Original Doubly linked list:" );
list.printList(head);
Node sortedDLL = list.sortAKSortedDLL(head, k);
Console.WriteLine( "" );
Console.WriteLine( "Doubly Linked List after sorting:" );
list.printList(sortedDLL);
}
}
|
Javascript
class Node {
constructor(val){
this .data = val;
this .next = null ;
this .prev = null ;
}
}
function sortAKSortedDLL(head, k)
{
if (head == null )
return head;
let pq = [];
let newHead = null ;
let last = null ;
for (let i = 0; head != null && i <= k; i++) {
pq.push(head);
pq.sort( function (a, b){
return a.data - b.data;
});
head = head.next;
}
while (pq.length > 0) {
if (newHead == null ) {
newHead = pq[0];
newHead.prev = null ;
last = newHead;
}
else {
last.next = pq[0];
pq[0].prev = last;
last = pq[0];
}
pq.shift();
if (head != null ) {
pq.push(head);
pq.sort( function (a, b){
return a.data - b.data;
});
head = head.next;
}
}
last.next = null ;
return newHead;
}
function push(head, new_data)
{
let new_node = new Node(new_data);
new_node.data = new_data;
new_node.prev = null ;
new_node.next = head;
if (head != null )
head.prev = new_node;
head = new_node;
return head;
}
function printList(head)
{
if (head == null )
console.log( "Doubly Linked list empty\n" );
let temp = "" ;
while (head != null ) {
temp = temp + head.data + " " ;
head = head.next;
}
console.log(temp);
}
let head = null ;
head = push(head, 8);
head = push(head, 56);
head = push(head, 12);
head = push(head, 2);
head = push(head, 6);
head = push(head, 3);
let k = 2;
console.log( "Original Doubly linked list:" );
printList(head);
head = sortAKSortedDLL(head, k);
console.log( "\nDoubly Linked List after sorting:" );
printList(head);
|
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(n*log k)
Auxiliary Space: O(k)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...