📜  对 K 排序的双向链表进行排序 |第 2 组(使用 Shell 排序)

📅  最后修改于: 2022-05-13 01:56:07.951000             🧑  作者: Mango

对 K 排序的双向链表进行排序 |第 2 组(使用 Shell 排序)

给定一个包含 N 个节点的双向链表,其中每个节点距列表中的目标位置最多 K,任务是对给定的双向链表进行排序。

例子:

注意:这里已经讨论了使用插入排序和使用最小堆数据结构的方法。

方法: Shell 排序是插入排序的一种变体,也可用于解决此问题,方法是使用K而不是N 来初始化间隙,因为列表已经是K 排序的。

以下是上述方法的实现:

Java
// Java implementation to sort a k sorted doubly
 
import java.util.*;
 
class DoublyLinkedList {
    static Node head;
    static class Node {
        int data;
        Node next, prev;
        Node(int d)
        {
            data = d;
            next = prev = null;
        }
    }
 
    // this method returns
    // the ceiling value of gap/2
    int nextGap(double gap)
    {
        if (gap < 2)
            return 0;
        return (int)Math.ceil(gap / 2);
    }
 
    // Sort a k sorted Doubly Linked List
    // Time Complexity: O(n*log k)
    // Space Complexity: O(1)
    Node sortAKSortedDLL(Node head, int k)
    {
        if (head == null || head.next == null)
            return head;
 
        // for all gaps
        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 data at jth node is less than
                // data at ith node
                if (i.data > j.data) {
 
                    // if i is head
                    // then replace head with j
                    if (i == head)
                        head = j;
 
                    // swap i & j pointers
                    Node iTemp = i;
                    i = j;
                    j = iTemp;
 
                    // i & j pointers are swapped because
                    // below code only swaps nodes by
                    // swapping their associated
                    // pointers(i.e. prev & next pointers)
 
                    // Now, swap both the
                    // nodes in linked list
                    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;
    }
 
    /* UTILITY FUNCTIONS */
    // Function to insert a node
    // at the beginning of the
    // Doubly Linked List
    void push(int new_data)
    {
        // allocate node
        Node new_node = new Node(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;
 
        // change prev of head node to new node
        if (head != null) {
            head.prev = new_node;
        }
 
        // move the head to point
        // to the new node
        head = new_node;
    }
 
    // Function to print nodes
    // in a given doubly linked list
 
    // This function is same as
    // printList() of singly linked list
    void printList(Node node)
    {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
        DoublyLinkedList list = new DoublyLinkedList();
 
        // 3<->6<->2<->12<->56<->8
        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);
    }
}


C#
// C# implementation to sort a k sorted doubly
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;
        }
    }
 
    // this method returns
    // the ceiling value of gap/2
    int nextGap(double gap)
    {
        if (gap < 2)
            return 0;
        return (int)Math.Ceiling(gap / 2);
    }
 
    // Sort a k sorted Doubly Linked List
    // Time Complexity: O(n*log k)
    // Space Complexity: O(1)
    Node sortAKSortedDLL(Node head, int k)
    {
        if (head == null || head.next == null)
            return head;
 
        // for all gaps
        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 data at jth node is less than
                // data at ith node
                if (i.data > j.data) {
 
                    // if i is head
                    // then replace head with j
                    if (i == head)
                        head = j;
 
                    // swap i & j pointers
                    Node iTemp = i;
                    i = j;
                    j = iTemp;
 
                    // i & j pointers are swapped because
                    // below code only swaps nodes by
                    // swapping their associated
                    // pointers(i.e. prev & next pointers)
 
                    // Now, swap both the
                    // nodes in linked list
                    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;
    }
 
    /* UTILITY FUNCTIONS */
    // Function to insert a node
    // at the beginning of the
    // Doubly Linked List
    void Push(int new_data)
    {
        // allocate node
        Node new_node = new Node(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;
 
        // change prev of head node to new node
        if (head != null) {
            head.prev = new_node;
        }
 
        // move the head to point
        // to the new node
        head = new_node;
    }
 
    // Function to print nodes
    // in a given doubly linked list
 
    // This function is same as
    // printList() of singly linked list
    void printList(Node node)
    {
        while (node != null) {
            Console.Write(node.data + " ");
            node = node.next;
        }
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        DoublyList list = new DoublyList();
 
        // 3<->6<->2<->12<->56<->8
        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);
    }
}
 
// This code is contributed by umadevi9616


Javascript


输出:
Original Doubly linked list:
3 6 2 12 56 8 
Doubly Linked List after sorting:
2 3 6 8 12 56

时间复杂度: O(N*log K)
gap 用 k 初始化,并在每次迭代后减小到 gap/2 的最大值。因此,将计算 log k 间隙,并且对于每个间隙,将迭代列表。

空间复杂度: O(1)