我正在尝试撤消链接列表:
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(打印功能很好)。
任何帮助?
由于
答案 0 :(得分:2)
既然你说你想自己找问题,我只会给你一个提示而不是解决方案。
您的reverse
功能的作用是成功撤消列表。那不是问题。您可能有2次拨打print
。一个在前面,一个在后面。在两种情况下,您对传递给print
的节点有何看法?这告诉你什么?
编辑:
既然你说你发现了问题,我会发布实际的解决方案。
在您的reverse
代码中,您永远不会更新列表的_head
,但是当您reverse
列表时,该网址实际上会从4
更改为{{ 1}}。由于您永远不会更新1
,当您第二次拨打_head
时(print
来电之后),您开始在reverse
打印,这就是列表的末尾,那是打印的唯一节点。
解决方法是在撤消列表时更新1
。最简单的方法是在每次迭代中简单地更新它。这可能比其他可能的解决方案效率稍低,但它不会改变算法的时间复杂度 - 它仍然是O(n):
_head
答案 1 :(得分:1)
尝试这样的事情。
双重链表:
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; }
}
答案 2 :(得分:0)
我喜欢递归;它更容易掌握和验证;
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;
}