【问题标题】:Reverse a linked list, is my idea correct?反转链表,我的想法正确吗?
【发布时间】:2021-05-18 18:52:43
【问题描述】:

我在读这个:https://www.geeksforgeeks.org/reverse-a-linked-list/

我想我找到了一个更简单的答案,但由于不是他们写的,而且他们使用了更复杂的答案,我认为我的问题有问题,无法弄清楚。

我们从第一个节点开始,我们将复制并将其插入到新列表中。 然后我们向右走一步,复制该值,使用该值创建一个新列表并将其设置为上一个列表的右侧等等。

我的算法有什么问题?

【问题讨论】:

  • 尝试编写代码,然后向我们展示您编写的内容。顺便说一句:在每次迭代中创建新列表似乎是一个非常糟糕的主意(时间成本、内存占用等)。
  • 老实说,我不明白该页面上通过动画 GIF 向您展示的与所述算法的偏离。它从字面上向您展示了如何做到这一点,甚至基本上为您提供了这样做的代码,而无需复制节点、节点值等。任务是反转链表;不要建立一个与另一个链表相反的链表,所呈现的图形算法正是你是如何做到的。
  • @VillageTech 但它是一个只有一个节点的列表,所以它是一个节点

标签: c++ list algorithm linked-list


【解决方案1】:

您的算法在功能上是正确的,但是由于您正在创建一个全新的列表而不是原地反转现有节点,因此您使用了两倍的内存。有了新列表后,您还必须处理删除旧节点的清理工作。

【讨论】:

  • "一旦有了新列表,您还必须处理删除旧节点的清理工作。"这是为什么?我将这些节点用作我正在构建的当前列表的最右边
  • @calc 您说您正在构建一个新列表。然后复制并插入到该列表中。这意味着分配节点,也意味着需要销毁旧节点。
  • @calc 由于您还没有接受尼克斯的回答(我认为这很正确),我添加了我自己的一个更详细的答案。
【解决方案2】:

如果我正确地解释了你的想法,它是这样的:

void forward_list::reverse() {
    forward_list new_list;

    for(auto& v : *this)
        new_list.emplace_front(std::move(v));

    std::swap(new_list, *this);   // or *this = std::move(new_list);
}

... 这会奏效。我会说它甚至看起来还不错。

我的算法有什么问题?

  • 它为每个旧节点创建一个新节点,然后必须将数据从旧节点复制/移动到新节点。旧节点将被销毁。
  • 某些类型甚至不可复制或移动,因此 reverse 算法无法用于此类类型。
  • 它使引用和迭代器无效。

考虑替代方案,反转链接。它有点复杂,但可以完成工作而没有上述任何缺点。

这是我对反转链接的看法,它的实现方式与您共享的链接中的方式不同,但它的工作方式几乎相同。我认为这个任务的任务较少。

curr 将指向head 前一步,next 用于在重新链接完成时保存next 指针。

void forward_list::reverse() {
    if(head) {                               // must have at least one node
        node* curr = head->next;             // head + 1
        head->next = nullptr;                // this will be the new last node
        node* next;                          // for saving next while relinking
        while(curr) {                        // while curr != nullptr
            next = curr->next;               // save the next pointer
            curr->next = head;               // relink backwards
            head = curr;                     // move head forward
            curr = next;                     // move curr forward
        }
        // head now points at the new start of the list automatically
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 2016-11-23
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多