反转两个节点之间的链表

Reversing a linked list between two nodes

本文关键字:节点 之间 链表 两个      更新时间:2023-10-16

我正在为一个CS类做一些功课,并且在一个旨在反转两个给定节点之间的双链表的函数上有点吃力。我很困惑自己做错了什么,我在谷歌和SO上搜索了一下,但找不到任何能帮助我的东西。

我有一个双链表,本质上我使用这个函数作为辅助函数,在作为函数参数的两个节点之间反转它。

下面是模板的代码,评论让你知道我的思考过程

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;
    }
}

那么,有什么想法吗?我知道问题发生在哪里,是什么,但我不明白为什么会发生,以及如何解决

此外,如果你认为我在做一些多余或不必要的事情,请随时告诉我,我有时会这样做。

EDIT:这是一个包含函数,因此如果您在链表{1,2,3,4,5,6}上调用它,指针指向值为2和5的节点,则链表将更改为{1、5、4、3,2,6}

问题出在子列表的末尾。

您还没有给出一个完整的示例(这会有所帮助),但假设我们从列表{1,2,3,4,5}开始,然后尝试reverse(s, e),其中se是指向2和4的指针。(所以我们想要的结果是{1,4,3,2,5}。)

这就是我在ASCII艺术方面失败的地方,但"next"answers"prev"指针看起来是这样的:

1-->2-->3-->4-->5
1<--2<--3<--4<--5

当控制离开while循环时,它们看起来像这样:

1<->2<--3   4-->5
1   2-->3<->4<--5

这几乎是我们想要的,但这个过程很快就停止了一个节点(4还没有逆转)。在它被"集成到列表的其余部分"之后,它们看起来是这样的:

  ________ ___
 /   /       
1   2<--3  >4-->5
1   2-->3-->4   5
 ________/___/

不太清楚,但如果你从列表的开头开始并向前移动,它会变成{1,4,5},如果你从末尾向后移动,它就会变成{5,2,3,4,1}。您已经打破了双链接条件,即如果a.next指向b,则b.prev指向a,反之亦然。

我的建议(除了用铅笔和纸画更多的箭头外)是从列表中删除子列表,将其反转,然后重新拼接;试图扭转这种局面是令人困惑的。