反向链表导致循环

Posted

技术标签:

【中文标题】反向链表导致循环【英文标题】:Reverse linked list causes a loop 【发布时间】:2020-05-05 21:45:41 【问题描述】:

为什么会导致循环?

我正在尝试使用迭代方法做一个反向链表,但是在遍历头节点时会发生循环(例如 print())。我已经用 C# 试过了,没有问题(当然是修改了语法)。

struct Node 
  int data;
  Node* next;
;

void
Reverse(Node& head_ref) 

  Node* current = &head_ref, *next = nullptr, *prev = nullptr;

  while (current != nullptr) 
    next = current->next;
    current->next = prev;
    prev = current;
    current = next;
  
  head_ref = *prev; //strange phenomenon happened here after head_ref is set.


int
main() 

  Node* head = new Node();
  Node* first = new Node();

  head->data = 1;
  head->next = first;

  first->data = 2;
  first->next = nullptr;

  Reverse(*head);

  while (head != nullptr)  // <-- infinite loop
    cout << head->data << endl;
    head = head->next;
  

  return 0;


prev 变量在 Reverse(...) 方法中返回:

0x0108ed10 data=2 next=0x00eff190 data=1 next=0x00000000 <NULL>  
    data: 2
    next: 0x00eff190 data=1 next=0x00000000 <NULL> 

head_ref 设置后会创建一个循环链表:

0x0108ed10 data=2 next=0x00eff190 data=2 next=0x00eff190 data=2 next=0x00eff190 data=2 next=0x00eff190 ...    
    data: 2
    next: 0x00eff190 data=2 next=0x00eff190 data=2 next=0x00eff190 data=2 next=0x00eff190 data=2 next=0x00eff190 ...    

【问题讨论】:

值得在调试器中单步执行,看看这是否真的正常工作。 遍历节点时会发生循环(例如 print())。不知道为什么代码会导致循环链表。 如果您不调试,至少打印指针以查看它们何时开始重新出现。这可能会提供线索。 如果您无意中创建了一个循环,您的打印代码将永远不会停止运行。 【参考方案1】:

head_ref = *prev; 覆盖Node,因为head_refNode&amp;,而不是Node*&amp;。而您打算更新head 指针,而不是整个Node head_ref 指代。

一个解决方法是:

void Reverse(Node*& head) 
    Node* current = head;
    // ...
    head = prev;

// ...
Reverse(head);

或者:

Node* Reverse(Node* head) 
    Node* current = head;
    // ...
    return prev;

// ...
head = Reverse(head);

【讨论】:

后一种解决方案对我有用。谢谢!但是,这里的代码没有创建循环。 void Reverse(Node& head_ref) Node* temp = &head_ref;临时->数据= 30;临时->下一个->数据 = 40; head_ref = *温度; @Binary01 在实现列表时,您可能希望只使用Node* 以保持一致性。

以上是关于反向链表导致循环的主要内容,如果未能解决你的问题,请参考以下文章

数据结构开发:循环链表与双向链表

JAVA 链表操作:循环链表

循环链表和双向链表

循环链表和双向链表

数据结构学习笔记(单链表单循环链表带头双向循环链表)的增删查改排序等)

数据结构学习笔记(单链表单循环链表带头双向循环链表)的增删查改排序等)