c++ - 合并链表

标签 c++ singly-linked-list

我试图在没有就位的情况下在 C++ 中合并两个链表。但是每次创建的新列表在到达一个或另一个列表的 nullptr 后都会发出以下数字。

MyLinkedList mergeTwoLinkedList(MyLinkedList b) {
        MyLinkedList c;

        node *tempa = this->head;
        node *tempb = b.head;

        if (b.head == nullptr)
            return *this;

        if (this->head == nullptr)
            return b;

        if (tempa && tempb) {
            do
            {
                if ((tempa->val) <= (tempb->val)) {
                    c.addAtTail(tempa->val);
                    tempa = tempa->next;

                } else if ((tempa->val) >= (tempb->val)) {
                    c.addAtTail(tempb->val);
                    tempb = tempb->next;
                }
            }
            while (tempa && tempb);
            return c;
        }
}

最佳答案

这是归并排序的一种非常常见的模式。让我首先通过删除冗余测试来简化您的循环(因为如果值 A 不小于等于 B,则根据定义它大于)。

while (tempa && tempb)
{
    if (tempa->val <= tempb->val) {
        c.addAtTail(tempa->val);
        tempa = tempa->next;
    } else {
        c.addAtTail(tempb->val);
        tempb = tempb->next;
    }
}

因此,将要发生的是,只要任一列表到达末尾,您的循环就会结束,不再添加任何值。

在我看来,这个问题最简单和最易读的解决方案是在之后再添加两个循环,它只是附加剩余的尾部:

for(; tempa; tempa = tempa->next)
{
    c.addAtTail(tempa->val);
}

for(; tempb; tempb = tempb->next)
{
    c.addAtTail(tempb->val);
}

其他解决方案很常见,其中主循环直到两个指针都为 NULL 才终止,但这需要在循环内进行更多测试,这可能会降低性能并肯定会降低可读性。

现在,如果您确实将其用于归并排序,您甚至不需要单独的列表。您可以通过修补列表节点将一个列表合并到另一个列表中。这使得添加整个尾部成为 O(1) 操作,这意味着在合并期间不会发生分配。如果合适,我会把它留给你作为练习。

关于c++ - 合并链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57422985/

相关文章:

C堆栈使用数组

使用 template<class T> 错误 :. 时的 c++。不是一个类

c++ - 临界区数据的原子操作

c - 链表中的节点是单独的结构还是同一结构的一部分?

c - 来自 gdb 调试器的 "Program received signal SIGSEGV, Segmentation fault."错误消息

c - 我无法在链表中使用链表

java - 从链表中删除相同的元素

c++ - 尝试编译或创建新文件时出现 "An assertion failed!"错误的代码块

c++ - 删除指向不完整类型和智能指针的指针

c++ - 使用字符串类型的键存储散列值的最佳结构