反转两个节点之间的链表

时间:2015-02-20 23:28:24

标签: c++ data-structures linked-list doubly-linked-list

我正在为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}

1 个答案:

答案 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,反之亦然。

我的建议(除了用铅笔和纸张绘制更多箭头)是从列表中删除子列表,反转它,然后将其拼接回来;试图扭转它是令人困惑的。