【问题标题】:Merge Sort on Doubly Linked List双向链表上的合并排序
【发布时间】:2022-01-04 23:17:10
【问题描述】:

如何合并 2 个给定的 DList,而不必先对它们进行排序? 当我在屏幕上显示时,我的排序功能似乎不起作用(它不合并项目)

DoublyLinkedList MergeSort(DoublyLinkedList &ls1, DoublyLinkedList &ls2)
{
    DoublyLinkedList ls;
    Initial(ls);
    if(isEmpty(ls1))
        return ls2;
    if(isEmpty(ls2))
        return ls1;
    if(ls1.head->data <= ls2.head->data)
    {
        InsertLast(ls, ls1.head->data);
        RemoveFirst(ls1);
    }
    else
    {
        InsertLast(ls, ls2.head->data);
        RemoveFirst(ls2);
    }
    ls = MergeSort(ls1, ls2);
    return ls;
}

这是我的主要内容

int main()
{
    DoublyLinkedList ls1,ls2,ls;
    Initial(ls1);
    Initial(ls2);
    Initial(ls);
    InsertLast(ls1, 9);
    InsertLast(ls1, 5);
    InsertLast(ls1, 1);
    InsertLast(ls1, 4);
    InsertLast(ls1, 3);
    InsertLast(ls2, 12);
    InsertLast(ls2, 6);
    InsertLast(ls2, 2);
    ls=MergeSort(ls1, ls2);
    Print(ls);
    return 0;
}

输出:9 5 1 4 3 12 6 2

【问题讨论】:

  • 您需要先对列表进行排序,然后才能合并它们。幸运的是,任何零项或一项列表都已经为您排序,两项列表可以使用单个(比较两个项和交换如果需要)进行排序。对于任何长度超过两个项目的列表,您始终可以将列表切割成两个较小的列表,然后在两个较小的列表中的每一个上递归调用您的排序函数,然后将两个现在排序的列表重新合并在一起。
  • @Arkadian 是的,这就是归并排序的工作原理——通过将较短的 排序 列表合并到较长的排序列表中。如果不需要进行预排序,那将是一个“sub-nlogn”(实际上是线性的)通用排序算法,它有点像perpetuum mobile的计算机科学等价物。
  • @AndrejPodzimek 我可以猜到你为什么说“线性”,但实际上如果不需要预排序,那么结果将是恒定时间排序。获取未排序的列表并将其与空列表合并。 :)
  • @JaMiT 我可能低估了perpetuum mobile的真正潜力,但也许不会……线性与恒定的结果取决于魔术 merging 与空列表完成。我会假设仍然需要对整个未排序列表做某事,而不仅仅是对空列表,所以它仍然是线性魔法,而不是恒定魔法。
  • 你能添加你调用的函数和你使用的结构/类的定义吗?

标签: c++ algorithm data-structures doubly-linked-list


【解决方案1】:

在咨询 cmets 后,我修复了该功能。重用 QSort 对给定的列表进行排序

DoublyLinkedList MergeSort(DoublyLinkedList &ls1, DoublyLinkedList &ls2)
{
    DoublyLinkedList ls;
    Initial(ls);
    if(isEmpty(ls1))
        return ls2;
    else if(isEmpty(ls2))
        return ls1;
    QuickSort(ls1);
    QuickSort(ls2);
    Node *p = ls1.head;
    Node *q = ls2.head;
    while(p != NULL && q != NULL)
    {
        if(p->data <= q->data)
        {
            InsertLast(ls, p->data);
            p = p->next;
        }
        else
        {
            InsertLast(ls, q->data);
            q = q->next;
        }
    }
    while(p != NULL)
    {
        InsertLast(ls, p->data);
        p = p->next;
    }
    while(q != NULL)
    {
        InsertLast(ls, q->data);
        q = q->next;
    }
    return ls;
}

这是我的子函数(InsertLast)

void InsertLast(DoublyLinkedList &ls, int data)
{
    Node *p = CreateNode(data);
    if(p == NULL)
        return;
    if(isEmpty(ls))
    {
        ls.head = ls.tail = p;
    }
    else
    {
        ls.tail->next = p;
        p->prev = ls.tail;
        ls.tail = p;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 2020-09-25
    • 2018-12-25
    • 1970-01-01
    相关资源
    最近更新 更多