📜  排序 ak 排序双向链表

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

排序 ak 排序双向链表

给定一个包含n 个节点的双向链表,其中每个节点最多距离列表中的目标位置k 。问题是对给定的双向链表进行排序。
例如,让我们考虑k是 2,排序双向链表中位置 7 处的节点可以位于给定双向链表中的位置 5、6、7、8、9。
例子:

朴素方法:使用插入排序技术对给定的双向链表进行排序。在列表的排序部分插入每个元素时,最多将有 k 次交换以将元素放置到其正确位置,因为它距其正确位置最多 k 步。

C++
// C++ implementation to sort a k sorted doubly
// linked list
#include
using namespace std;
 
// a node of the doubly linked list
struct Node {
    int data;
    struct Node* next;
    struct Node* prev;
};
 
 
// function to sort a k sorted doubly linked list
struct Node* sortAKSortedDLL(struct Node* head, int k)
{
    if(head == NULL || head->next == NULL)
        return head;
  
    // perform on all the nodes in list
    for(Node *i = head->next; i != NULL; i = i->next) {
        Node *j = i;
          // There will be atmost k swaps for each element in the list
        // since each node is k steps away from its correct position
        while(j->prev != NULL && j->data < j->prev->data) {
              // swap j and j.prev node
            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 is now the new head
       // then reset head
        if(j->prev == NULL)
            head = j;
    }
    return head;
}
 
// 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:
    // 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;
}
 
// This code is contributed by sachinejain74754.


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;
    }
}
 
// function to sort a k sorted doubly linked list
// Using Insertion Sort
// Time Complexity: O(n*k)
// Space Complexity: O(1)
Node sortAKSortedDLL( Node head, int k) {
      if(head == null || head.next == null)
        return head;
 
    // perform on all the nodes in list
    for(Node i = head.next; i != null; i = i.next) {
        Node j = i;
          // There will be atmost k swaps for each element in the list
        // since each node is k steps away from its correct position
        while(j.prev != null && j.data < j.prev.data) {
              // swap j and j.prev node
            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 is now the new head
       // then reset head
        if(j.prev == null)
            head = j;
    }
    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();
 
    /* Let us create a k sorted doubly linked list to test the
        functions Created doubly linked list will be 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);
}
}
 
// This code is contributed by Mittul Mandhan(@mittulmandhan)


Javascript


CPP
// C++ implementation to sort a k sorted doubly
// linked list
#include 
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' implemented as min heap with the
    // help of 'compare' function
    priority_queue, 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 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:
    // 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;
}


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;
    }
  }
  class compareNode implements Comparator
  {
    public int compare(Node n1, Node n2){
      return n1.data-n2.data;
    }
  }
 
  // function to sort a k sorted doubly linked list
  Node sortAKSortedDLL( Node head, int k)
  {
     
    // if list is empty
    if (head == null)
      return head;
 
    // priority_queue 'pq' implemented as min heap with the
    // help of 'compare' function in compare Node class
    PriorityQueue pq = new PriorityQueue(new compareNode());
 
    Node newHead = null, last = null;
 
    // 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.add(head);
 
      // move to the next node
      head = head.next;
    }
 
    // loop till there are elements in 'pq'
    while (!pq.isEmpty())
    {
 
      // 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.peek();
        newHead.prev = null;
 
        // 'last' points to the last node
        // of the result sorted list so far
        last = newHead;
      }
 
      else
      {
        last.next = pq.peek();
        pq.peek().prev = last;
        last = pq.peek();
      }
 
      // remove element from 'pq'
      pq.poll();
 
      // if there are more nodes left in the input list
      if (head != null)
      {
         
        // push the node on to 'pq'
        pq.add(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;
  }
 
  /* 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();
 
    /* Let us create a k sorted doubly linked list to test the
         functions Created doubly linked list will be 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);
  }
}
 
// This code is contributed by Kushagra Keserwani


输出

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

时间复杂度: O(n*k)

辅助空间: O(1)

有效的方法:我们可以使用 MIN HEAP 数据结构对列表进行排序。该方法已在对近似排序(或 K 排序)数组排序中进行了解释。我们只需要在遍历输入的双向链表并调整最终排序列表中所需的下一个上一个链接时小心。

CPP

// C++ implementation to sort a k sorted doubly
// linked list
#include 
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' implemented as min heap with the
    // help of 'compare' function
    priority_queue, 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 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:
    // 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;
}

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;
    }
  }
  class compareNode implements Comparator
  {
    public int compare(Node n1, Node n2){
      return n1.data-n2.data;
    }
  }
 
  // function to sort a k sorted doubly linked list
  Node sortAKSortedDLL( Node head, int k)
  {
     
    // if list is empty
    if (head == null)
      return head;
 
    // priority_queue 'pq' implemented as min heap with the
    // help of 'compare' function in compare Node class
    PriorityQueue pq = new PriorityQueue(new compareNode());
 
    Node newHead = null, last = null;
 
    // 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.add(head);
 
      // move to the next node
      head = head.next;
    }
 
    // loop till there are elements in 'pq'
    while (!pq.isEmpty())
    {
 
      // 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.peek();
        newHead.prev = null;
 
        // 'last' points to the last node
        // of the result sorted list so far
        last = newHead;
      }
 
      else
      {
        last.next = pq.peek();
        pq.peek().prev = last;
        last = pq.peek();
      }
 
      // remove element from 'pq'
      pq.poll();
 
      // if there are more nodes left in the input list
      if (head != null)
      {
         
        // push the node on to 'pq'
        pq.add(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;
  }
 
  /* 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();
 
    /* Let us create a k sorted doubly linked list to test the
         functions Created doubly linked list will be 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);
  }
}
 
// This code is contributed by Kushagra Keserwani
输出
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)
辅助空间: O(k)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程