链表的反转问题

来源:互联网 发布:tom围棋 mac 编辑:程序博客网 时间:2024/06/15 21:22

思路:所谓反转链表就是指将这个链表的所有指针方向反向。

采取的办法是时刻保留连续的3个结点,ppre/pcur/pnext;

修改指针方向:将pcur.next设置为ppre;

然后修改ppre/pcur/pnext向前推进即可

ppre=pcur;

pcur=pnext;

pnext=pnext.next;

需要注意的是:

1.          输入的链表head==null;

2.          输入的链表只有一个结点,直接返回head

3.          当pnext==null时,就要停止,因为此时pnext.next是非法的,空指针异常,应该停止然后手动完成最后一次指针反向pcur.next设置为ppre。




/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/

 

//所谓反转链表即将整个链表的指针反向,所谓输出链表的所有元素即为输出链表的头结点

publicclass Solution {

    public ListNode ReverseList(ListNode head){

        //定义三个属性,记录连续的3个结点

        ListNode ppre=null;

        ListNode pcur=head;   

        if(head==null){

            //输入空结点

            return null;

        }

        ListNode pnext=head.next;  

        if(pnext==null){

            //输入的链表只有一个结点

           return head;

        }

        while(pnext!=null){

            //修改指针方向

            pcur.next=ppre;

            //修改ppre/pcur/pnext

            ppre=pcur;

            pcur=pnext;

            pnext=pnext.next;

        }

         pcur.next=ppre;

        return pcur;

    }

}

需要注意的是ppre一开始是null,这是因为第一个节点的前一个节点就是空。并且在反转之后原本是第一个节点的下一个节点就是空。


对于这个算法来说,还可以使用栈来实现,虽然使用栈比上面的算法要简单,但是需要额外的空间,空间复杂度为o(n)。而上面的空间复杂度为o(1)。