我正在为CS课程做一些功课,并且正在努力解决一个功能,这个功能意味着在两个给定节点之间反转双向链表。我对我做错了什么感到很困惑,而且我已经搜索了谷歌等等,我找不到任何可以帮助我的东西。
我有一个双向链表,我基本上使用这个函数作为辅助函数在两个节点之间反转它,这两个节点作为函数的参数给出。
以下是模板的代码,注释以便您了解我的思维过程
template <class T>
void List<T>::reverse( ListNode * & startPoint, ListNode * & endPoint )
{
//make sure that none of the pointers are null and that the start and
//end points aren't the same
if(startPoint == NULL || endPoint == NULL || startPoint == endPoint)
return;
//Make two nodes denoting everything happening before the
//start and everything after the end
ListNode *before = NULL;
ListNode *after = NULL;
if(startPoint->prev != NULL)
before = startPoint->prev;
if(endPoint->next != NULL)
after = endPoint->next;
ListNode *temp = startPoint;
ListNode *temp2;
//run a loop actually reversing the list. I have identified
//that this is where the problem is happening (obviously)
//for some reason the prev pointer for every node is being set to null
//so if I had a linked list with 1 2 3 4 5
//after running this it's just 5
while(temp!=endPoint && temp!=NULL){
temp2 = temp->next;
if(temp->prev!=NULL);
temp->next = temp->prev;
if(temp2!=NULL)
temp->prev = temp2;
temp = temp2;
}
//switch around the end and start pointers
endPoint = startPoint;
startPoint = temp;
//make sure it's integrated into the rest of the linked list
if(before != NULL){
before->next = startPoint;
startPoint->prev = before;
}
if(after != NULL){
after->prev = endPoint;
endPoint->next = after;
}
}
那么,有什么想法吗? 我已经知道问题发生在哪里,它是什么,但我不明白它为什么会发生,以及如何解决它。
此外,如果您认为我做了多余或不必要的事情,请随时告诉我。我有时会这样做。
编辑:这是一个包容性函数,所以如果你在一个链接列表{1,2,3,4,5,6}上调用它,指针指向值为2和5的节点,那么链表就是改为{1,5,4,3,2,6}答案 0 :(得分:1)
问题在于子列表的末尾。
你还没有给出一个完整的例子(这会有所帮助),但假设我们从列表{1,2,3,4,5}开始,我们尝试reverse(s, e)
,其中{{1 }和s
是指向2和4的指针。(所以我们期望的结果是{1,4,3,2,5}。)
这是我的ASCII艺术技能失败的地方,但'next'和'prev'指针看起来像这样:
e
当控件离开1-->2-->3-->4-->5
1<--2<--3<--4<--5
循环时,它们看起来像这样:
while
这几乎是我们的意图,但是这个过程很快就停止了一个节点(4没有被逆转)。在“集成到列表的其余部分”之后,它们看起来像这样:
1<->2<--3 4-->5
1 2-->3<->4<--5
不是很清楚,但是如果你从列表的开头开始向前移动,它会进入{1,4,5},如果你从末尾向后移动它会进入{5,2,3,4, 1}。您已经打破了双重关联条件,即如果 ________ ___
/ / \ \
1 2<--3 >4-->5
1 2-->3-->4 5
\___\_____/___/
指向a.next
,则b
指向b.prev
,反之亦然。
我的建议(除了用铅笔和纸张绘制更多箭头)是从列表中删除子列表,反转它,然后将其拼接回来;试图扭转它是令人困惑的。