反转链表是一个挺有趣的问题。我们可以化为两个链表的衔接和断开问题。
为了形象说明假设有两条链表L1和L2(转换过程中只有一条),以蓝色的节点为L1的节点,红色的节点为L2的节点。其中L2为L1的反转链表。
要从L1转换到转换到L2。可以看出从L1开始截取当前一个节点作为L2的头,被截取节点的下一节点为,L1的新头,然后把L1的心头指向L2的头,不断重复直到转换完毕,说的比较抽象下面用图来说明。
① ② ③ 好了,就到这里不演示全部转换过程,可以看到在转换过程中是原链表发生了断裂。 从图可以看出,这是可以通过遍历L1来完成转换。那么就有两个问题要解决。 ①在遍历过程中转换形式?②如何设置转换结束条件,以及转换开始前需要什么条件(一定是单纯的遍历一遍吗?)?为了使得链表能够连接上,我们需要保存断开处,两侧的节点信息,同时为了使得能够用循环进行转换,我们还需要保存新链表头的后继节点。 分别用pre,pnode,pnext,三个指针来寻址。
以上图为例,转换过程的逻辑 pnode->next = pre; pre = pnode; pnode = pnext; pnext = pnext->next;可以在纸上画一画过程,很直观。
下面上代码
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* ReverseList(ListNode* pHead) { ListNode* pre = NULL; ListNode* pnode = pHead; ListNode* preverhead = NULL; while(pnode != NULL)//循环结束条件尾pnode == NULL { ListNode* pnext = pnode->next; if(pnext == NULL)//如果pnode指向了原链表的尾 preverhead = pnode; pnode->next = pre; pre = pnode; pnode = pnext; } return preverhead; } };