排序 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 现场工作专业课程和学生竞争性编程现场课程。