【问题标题】:Why does this code fail to reverse a doubly linked list为什么这段代码无法反转双向链表
【发布时间】:2017-01-11 15:15:33
【问题描述】:

我试图避免在这里问这个问题,但是在看了将近一个小时的同一段代码之后,我真的不知道为什么下面的代码无法反转双向链表:

Node* Reverse(Node* head) {
    if (head == nullptr) {return head;}
    Node *iter = head, *tail, *newTail;
    while (iter -> next != nullptr) {iter = iter -> next;} //to set the tail pointer
    tail = iter;
    newTail = tail; //the node that will become the tail after reversing is done
    iter = head;

    while (iter != tail) {
        newTail -> next = iter;
        iter -> prev = newTail;
        newTail = iter;
        iter = iter -> next;
    }

    newTail -> next = nullptr;
    tail -> prev = nullptr;
    return tail;
}

我将不胜感激。

编辑 似乎代码与我的想法无关。哇。附带说明一下,我只完成了不涉及指针的入门编程课程,更不用说链表等了。谢谢你的帮助!

最终代码 如果你有兴趣,我已经完成了我的反转双向链表的算法。我认为这是一个不错的方法,尽管我当然愿意接受建议。

node *reverse(node *head)
{
    if (head == nullptr) {return head;}
    node *iter, *tail, *temp, *newTail;
    while (iter -> next != nullptr) {iter = iter -> next;}
    tail = iter;
    newTail = tail;
    iter = tail -> prev;
    while (iter != nullptr)
    {
        temp = iter -> prev;
        newTail -> next = iter;
        iter -> prev = newTail;
        newTail = iter;
        iter = temp;
    }
    tail -> prev = nullptr;
    newTail -> next = nullptr;
    return tail;
}

【问题讨论】:

  • 我的工作方式会有所不同。首先到达尾部,然后建立一个新列表。并且总是预取下一个元素。我还要说,在代码操作过程中改变 newTail 的语义是代码异味,可能会导致混乱。还有错误。

标签: c++ linked-list reverse doubly-linked-list


【解决方案1】:

在代码中,newTail 总是在 iter 后面。在 while 循环内部,newTail->next 设置为 iter,iter->prev 设置为 newTail。没有效果。

也许这张图会有所帮助

试试这个。它循环遍历列表,并为每个节点交换 next 和 prev 指针。 (这可能不是最有效的算法。)

Node* Reverse2(Node* head) {
  if (head == nullptr) {return head;}
  Node *iter = head;

  Node *tail = nullptr;
  while (iter!=nullptr) {
    tail = iter; //keep track of tail

    Node *tmp = iter->next; //before swap, pre-fetch next node

    swap(iter);

    iter=tmp; //go to next node
  }

  return tail;

}

void swap(Node *n) {
  Node *tmp = n->prev;
  n->prev = n->next;
  n->next = tmp;
}

【讨论】:

  • 感谢您的解释性回复。我想到了你建议的算法,但我想做一些不同的事情,因为它感觉像是一种反转列表的常用方法。我已经编辑了我的初始帖子,请随时查看!
【解决方案2】:

假设您有 3 个元素,将它们编号为 0、1、2。因此,您从指向最后一个元素 (2) 的 newTail 开始。然后从头开始 (0) 并设置 newTail->next = iter。那么现在 2 链接到 0 了吗?这听起来不像是颠倒列表。

【讨论】:

    猜你喜欢
    • 2012-06-25
    • 2020-07-11
    • 2018-09-23
    • 1970-01-01
    • 2016-08-09
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    相关资源
    最近更新 更多