1.题目描述
输入一个链表,反转链表后,输出链表的所有元素。
2.思路
next = head.next; // 1
head.next = pre; // 2
pre = head; // 3
head = next; // 4
第一行代码:next = head.next;
将head.next赋值给next变量,也就是说next指向了节点2,先将节点2保存起来。
第二行代码: head.next = pre;
将pre变量赋值给了head.next,即节点1指向了null。
第三行代码:pre = head;
将head赋值给了pre,即pre指向节点1,将节点1设为“上一个节点”。
第四行代码:head = next;
将next赋值给head,即head指向了节点2。将节点2设置为“头结点”。
一次循环的具体过程就是这样。
所以总结一下单链表的反转:
1.保存当前头结点的下个节点。
2.将当前头结点的下一个节点指向“上一个节点”,这一步是实现了反转。
3.将当前头结点设置为“上一个节点”。
4.将保存的下一个节点设置为头结点。
更具体思路:
1.pHead为当前结点,如果当前结点为空的话,直接返回;
2.pHead为当前结点,pre为当前结点的前一个结点,next为当前结点的下一个结点;
3.需要完成的目标是将pre–>pHead–>next1–>next2–>··· ···–>end反转为pre<–pHead<–next1<–next2<–··· ···<–end;
4.pre结点可以用来反转方向,为了避免反转之后链表断开,用next结点暂时保存next1结点;
5.先用next保存pHead的下一个结点信息,保证单链表不会断裂;
6.保存之后,让pHead从指向next变成指向pre;
7.到此,完成了pre到pHead的反转,即pre<–pHead;
8.将pre,pHead,next依次向后移动一个结点。
9.循环操作,直到pHead为null,此时pre就是链表的最后一个结点,链表反转完毕,pre为反转后链表的第一个结点。
10.输出pre就是反转之后所得的链表。
3.代码
/*
题目:
给了链表头结点,翻转链表
*/
function ListNode(val) {
this.val = val;
this.next = null;
}
/*
思路:
假设现在到了节点i,首先拿到i+1的节点保存在nextNode当中,防止断链。然后将i节点的next指向i-1节点,这个i-1节点保存在pre当中。
然后置pre为当前节点i,下一个节点变成nextNode
也就是nextNode = pHead.next;
pHead.next = pre;
pre = pHead;
pHead = nextNode;
最后pHead节点为null,表示链表遍历完成,返回上一节pre,即翻转后的头结点
*/
function reverseList(head) {
let pHead = head;
//初始化
let pre = null;//保存上一个节点,之后节点的指向
let nextNode = null;//保存下一个节点,不断链
while(pHead) {
nextNode = pHead.next;
pHead.next = pre;
pre = pHead;
pHead = nextNode;
}
return pre;
}
参考文章:
https://www.jianshu.com/p/bd6a64d36916
https://www.cnblogs.com/echovic/p/6430681.html
https://www.cnblogs.com/wuguanglin/p/ReverseList.html
https://github.com/DavidChen93/-offer-JS-/blob/master/24.1 翻转链表.js