【问题标题】:Reverse a LinkedList c++ [duplicate]反转链接列表c ++ [重复]
【发布时间】:2012-10-23 15:10:00
【问题描述】:

可能重复:
Unable to reverse a linked list

我正在尝试反转一个链表:

void LinkedList::reverseList()
{
    Node *next=_head;
    Node *prev=0;
    while(next!=0)
    {
        Node *tmp=next->_next;
        next->_next=prev;
        prev=next;
        next=tmp;
    }
}

假设列表是:4->3->2->1

打印列表时,我只看到1(打印功能不错)。

有什么帮助吗?

谢谢

【问题讨论】:

  • 对,是C++,给Node一些方法。让他们交换他们在列表中的位置而不交换他们的值。然后找到列表的两端并交换它们,沿着你的方式工作,直到你到达两端的相同节点或刚刚交换的节点。
  • 你从不分配_head,是吗?
  • while循环之后添加_head = prev;
  • 我试过了,没用。我仍然得到 >>1 作为输出。
  • 应该,真的。如果您在while 循环之后添加_head = prev,您的代码与我的答案here 完全相同。我也在LWS上尝试并验证过。

标签: c++ linked-list reversing


【解决方案1】:

既然你说你想自己找到问题,我就给你一个提示而不是解决方案。

您的reverse 函数可以成功地反转列表。那不是问题。您可能有 2 个电话给 print。一个前一个后一个反向。在这两种情况下,您对传递给print 的节点有何注意事项?这告诉你什么?

编辑:

既然你说你找到了问题,那我就贴出实际的解决方案。

在您的reverse 代码中,您永远不会更新列表的_head,但是当您reverse 列表时,头部确实从4 更改为1。由于您从不更新_head,因此当您第二次调用print 时(在reverse 调用之后),您将在1 开始打印,这是列表的末尾,这是唯一打印的节点。

解决方案是在反转列表时更新_head。最简单的方法是在每次迭代中简单地更新它。这可能比其他可能的解决方案效率略低,但它不会改变算法的时间复杂度——它仍然是 O(n):

void LinkedList::reverseList()
{
    Node *next=_head;
    Node *prev=0;
    while(next!=0)
    {
        Node *tmp=next->_next;
        next->_next=prev;
        _head = next;
        prev=next;
        next=tmp;
    }
}

【讨论】:

  • printList 函数不接收任何参数,它从 _head 开始,然后一直移动到列表的末尾(直到 0 是最后一个节点的下一个节点)..
  • 现在我明白了.. 非常感谢:)
  • 不客气。你想让我现在发布解决方案吗?
  • 当然.. 现在我修好了 :) 我应该在 _head 的副本上“旅行”,而不是在打印功能上使用 _head 本身。
  • @Maroun:哎呀,这是个坏主意,是的。 :) 你会注意到,如果你让你的print 成员const,不过!如void print() const{ ... }
【解决方案2】:

试试这样的。

双向链表:

for (Node * n = _head, * next; ; n = next)
{
    next = n->next;

    std::swap(n->next, n->prev);

    if (next == NULL) { _head = n; break; }
}

单链表:

for (Node * n = _head, * prev = NULL, * next; ; prev = n, n = next)
{
    next = n->next;

    n->next = prev;

    if (next == NULL) { _head = n; break; }
}

【讨论】:

  • 我的第一个想法完全正确,但它似乎是一个单链表。
  • 从来没有提到过n->prev。 :)
  • 好的,我制作了两个版本,一个用于双列表,一个用于单列表。
  • 我会试试这个。有人能解释为什么我的代码不起作用吗?我在这里缺少什么?
  • @Maroun85:Xeo 不是已经解释了吗?您永远不会在代码中重新分配 _head
【解决方案3】:

我喜欢递归;更容易掌握和验证;

Node* LinkedList::reverseList() { // returns tail
  if (!_head || !_head->_next)
      return _head;
  Node* const h = _head;
  _head = _head->_next;
  h->_next = NULL;
  return reverseList()->_next = h;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-26
    • 2017-03-10
    • 2013-11-09
    • 2018-02-09
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多