Sort a K sorted Doubly Linked List | Set 2 (Using Shell Sort)
Given a doubly-linked list containing N nodes, where each node is at most K away from its target position in the list, the task is to sort the given doubly linked list.
Examples:
Input: DLL: 3<->6<->2<->12<->56<->8, K = 2
Output:
2<->3<->6<->8<->12<->56
Input: DLL: 3<->2<->1<->5<->4
Output:
1<->2<->3<->4<->5
Note: Approaches using Insertion sort and using Min Heap Data structure have been discussed here.
Approach: Shell sort, which is a variation of Insertion sort can be used to solve this problem as well, by initializing the gap with K instead of N, as the list is already K-sorted.
Below is an implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class Node {
public :
int data;
Node* next;
Node* prev;
Node( int d)
{
data = d;
next = prev = nullptr;
}
};
void printList(Node* node)
{
while (node != nullptr) {
cout << node->data << " " ;
node = node->next;
}
}
int nextGap( double gap)
{
if (gap < 2)
return 0;
return ( int )std:: ceil (gap / 2);
}
Node* sortAKSortedDLL(Node* head, int k)
{
if (head == nullptr || head->next == nullptr)
return head;
for ( int gap = k; gap > 0; gap = nextGap(gap)) {
Node *i = head, *j = head;
int count = gap;
while (count-- > 0)
j = j->next;
for (; j != nullptr; i = i->next, j = j->next) {
if (i->data > j->data) {
if (i == head)
head = j;
Node* iTemp = i;
i = j;
j = iTemp;
Node *iPrev = i->prev, *iNext = i->next;
if (iPrev != nullptr)
iPrev->next = j;
if (iNext != nullptr)
iNext->prev = j;
i->prev = j->prev;
i->next = j->next;
if (j->prev != nullptr)
j->prev->next = i;
if (j->next != nullptr)
j->next->prev = i;
j->prev = iPrev;
j->next = iNext;
}
}
}
return head;
}
void push(Node** head_ref, int new_data)
{
Node* new_node = new Node(new_data);
new_node->prev = nullptr;
new_node->next = *head_ref;
if (*head_ref != nullptr) {
(*head_ref)->prev = new_node;
}
*head_ref = new_node;
}
int main()
{
Node* head = nullptr;
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:" << std::endl;
printList(head);
Node* sortedDLL = sortAKSortedDLL(head, k);
cout << endl;
cout << "Sorted Doubly linked list:" << std::endl;
printList(sortedDLL);
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 ;
}
}
int nextGap( double gap)
{
if (gap < 2 )
return 0 ;
return ( int )Math.ceil(gap / 2 );
}
Node sortAKSortedDLL(Node head, int k)
{
if (head == null || head.next == null )
return head;
for ( int gap = k; gap > 0 ; gap = nextGap(gap)) {
Node i = head, j = head;
int count = gap;
while (count-- > 0 )
j = j.next;
for (; j != null ; i = i.next, j = j.next) {
if (i.data > j.data) {
if (i == head)
head = j;
Node iTemp = i;
i = j;
j = iTemp;
Node iPrev = i.prev, iNext = i.next;
if (iPrev != null )
iPrev.next = j;
if (iNext != null )
iNext.prev = j;
i.prev = j.prev;
i.next = j.next;
if (j.prev != null )
j.prev.next = i;
if (j.next != null )
j.next.prev = i;
j.prev = iPrev;
j.next = iNext;
}
}
}
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
class Node:
def __init__( self , data):
self .data = data
self . next = None
self .prev = None
class DoublyLinkedList:
def __init__( self ):
self .head = None
def next_gap( self , gap):
if gap < 2 :
return 0
return int (gap / 2 + 0.5 )
def sort_k_sorted_dll( self , head, k):
if not head or not head. next :
return head
for gap in range (k, 0 , - 1 ):
i = head
j = head
count = gap
while count > 0 and j:
j = j. next
count - = 1
while j:
if i.data > j.data:
if i = = head:
head = j
i_temp = i
i = j
j = i_temp
i_prev = i.prev
i_next = i. next
if i_prev:
i_prev. next = j
if i_next:
i_next.prev = j
i.prev = j.prev
i. next = j. next
if j.prev:
j.prev. next = i
if j. next :
j. next .prev = i
j.prev = i_prev
j. next = i_next
i = i. next
j = j. next
return head
def push( self , new_data):
new_node = Node(new_data)
new_node.prev = None
new_node. next = self .head
if self .head:
self .head.prev = new_node
self .head = new_node
def print_list( self , node):
while node:
print (node.data, end = " " )
node = node. next
if __name__ = = "__main__" :
dll = DoublyLinkedList()
dll.push( 8 )
dll.push( 56 )
dll.push( 12 )
dll.push( 2 )
dll.push( 6 )
dll.push( 3 )
k = 2
dll.print_list(dll.head)
sorted_dll = dll.sort_k_sorted_dll(dll.head, k)
print ( "\nDoubly Linked List after sorting:" )
dll.print_list(sorted_dll)
|
C#
using System;
public class DoublyList {
public static Node head;
public class Node {
public int data;
public Node next, prev;
public Node( int d)
{
data = d;
next = prev = null ;
}
}
int nextGap( double gap)
{
if (gap < 2)
return 0;
return ( int )Math.Ceiling(gap / 2);
}
Node sortAKSortedDLL(Node head, int k)
{
if (head == null || head.next == null )
return head;
for ( int gap = k; gap > 0; gap = nextGap(gap)) {
Node i = head, j = head;
int count = gap;
while (count-- > 0)
j = j.next;
for (; j != null ; i = i.next, j = j.next) {
if (i.data > j.data) {
if (i == head)
head = j;
Node iTemp = i;
i = j;
j = iTemp;
Node iPrev = i.prev, iNext = i.next;
if (iPrev != null )
iPrev.next = j;
if (iNext != null )
iNext.prev = j;
i.prev = j.prev;
i.next = j.next;
if (j.prev != null )
j.prev.next = i;
if (j.next != null )
j.next.prev = i;
j.prev = iPrev;
j.next = iNext;
}
}
}
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 ) {
Console.Write(node.data + " " );
node = node.next;
}
}
public static void Main(String[] args)
{
DoublyList list = new DoublyList();
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 nextGap(gap) {
if (gap < 2)
return 0;
return parseInt( Math.ceil(gap / 2));
}
function sortAKSortedDLL(head , k) {
if (head == null || head.next == null )
return head;
for ( var gap = k; gap > 0; gap = nextGap(gap)) {
var i = head, j = head;
var count = gap;
while (count-- > 0)
j = j.next;
for (; j != null ; i = i.next, j = j.next) {
if (i.data > j.data) {
if (i == head)
head = j;
var iTemp = i;
i = j;
j = iTemp;
var iPrev = i.prev, iNext = i.next;
if (iPrev != null )
iPrev.next = j;
if (iNext != null )
iNext.prev = j;
i.prev = j.prev;
i.next = j.next;
if (j.prev != null )
j.prev.next = i;
if (j.next != null )
j.next.prev = i;
j.prev = iPrev;
j.next = iNext;
}
}
}
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( "<br/>" );
document.write( "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*log K)
gap is initialized with k and reduced to the ceiling value of gap/2 after each iteration. Hence, log k gaps will be calculated, and for each gap, the list will be iterated.
Space Complexity: O(1)
Last Updated :
17 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...