📜  双向链表合并排序的C程序

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

双向链表合并排序的C程序

给定一个双向链表,编写一个函数,使用归并排序对双向链表进行升序排序。
比如下面的双向链表要改成24810

已经讨论了单链表的合并排序。这里的重要变化是在合并两个列表时也修改了先前的指针。

下面是双向链表合并排序的实现。

C
// C program for merge sort on doubly 
// linked list
#include
#include
struct Node
{
    int data;
    struct Node *next, *prev;
};
  
struct Node *split(struct Node *head);
  
// Function to merge two linked lists
struct Node *merge(struct Node *first, 
                   struct Node *second)
{
    // If first linked list is empty
    if (!first)
        return second;
  
    // If second linked list is empty
    if (!second)
        return first;
  
    // Pick the smaller value
    if (first->data < second->data)
    {
        first->next = merge(first->next,second);
        first->next->prev = first;
        first->prev = NULL;
        return first;
    }
    else
    {
        second->next = merge(first,second->next);
        second->next->prev = second;
        second->prev = NULL;
        return second;
    }
}
  
// Function to do merge sort
struct Node *mergeSort(struct Node *head)
{
    if (!head || !head->next)
        return head;
    struct Node *second = split(head);
  
    // Recur for left and right halves
    head = mergeSort(head);
    second = mergeSort(second);
  
    // Merge the two sorted halves
    return merge(head,second);
}
  
// A utility function to insert a new node 
// at the beginning of doubly linked list
void insert(struct Node **head, int data)
{
    struct Node *temp =
    (struct Node *)malloc(sizeof(struct Node));
    temp->data = data;
    temp->next = temp->prev = NULL;
    if (!(*head))
        (*head) = temp;
    else
    {
        temp->next = *head;
        (*head)->prev = temp;
        (*head) = temp;
    }
}
  
// A utility function to print a doubly 
// linked list in both forward and backward 
// directions
void print(struct Node *head)
{
    struct Node *temp = head;
    printf(
    "Forward Traversal using next pointer");
  
    while (head)
    {
        printf("%d ",head->data);
        temp = head;
        head = head->next;
    }
    printf(
    "Backward Traversal using prev pointer");
    while (temp)
    {
        printf("%d ", temp->data);
        temp = temp->prev;
    }
}
  
// Utility function to swap two integers
void swap(int *A, int *B)
{
    int temp = *A;
    *A = *B;
    *B = temp;
}
  
// Split a doubly linked list (DLL) into 
// 2 DLLs of half sizes
struct Node *split(struct Node *head)
{
    struct Node *fast = head,*slow = head;
    while (fast->next && fast->next->next)
    {
        fast = fast->next->next;
        slow = slow->next;
    }
    struct Node *temp = slow->next;
    slow->next = NULL;
    return temp;
}
  
// Driver program
int main(void)
{
    struct Node *head = NULL;
    insert(&head,5);
    insert(&head,20);
    insert(&head,4);
    insert(&head,3);
    insert(&head,30);
    insert(&head,10);
    head = mergeSort(head);
    printf(
    "Linked List after sorting");
    print(head);
    return 0;
}


输出:

Linked List after sorting
Forward Traversal using next pointer
3 4 5 10 20 30
Backward Traversal using prev pointer
30 20 10 5 4 3

时间复杂度:上述实现的时间复杂度与数组的 MergeSort 的时间复杂度相同。它需要 Θ(nLogn) 时间。

空间复杂度: O(1)。我们只使用恒定数量的额外空间。
您可能还想查看双向链表的快速排序
更多详细信息,请参阅关于双向链表合并排序的完整文章!