带有头节点的链表
思考:头插法,将遍历到的节点往前面添加;
public class ReverseList01 {
/**
* 定义链表节点
*/
public class Node {
public int val;
//指向下一个节点
public Node next;
//构造器
public Node(int no){
this.val = no;
}
@Override
public String toString() {
return "HeroNode[no=" + val + "]";
}
}
/**
* 单链表的反转
* @param head 传入需要进行反转的单链表
*/
public static void reverseLinkedHead(Node head) {
//1. 当链表为空或者只有一个节点时候,直接返回
if (head.next == null || head.next.next == null) return;
//2. 为了不破坏原有的链表,定义一个节点用来辅助的指针遍历
Node cur = head.next;
//3. 临时变量,用来进行位置互换
Node next = null;
//4. 初始化一个新的头节点,用来存放反转链表
Node reverseHead = new Node(0);
while (cur != null){
//保存当前节点的下一个节点,后面换完位置后需要复原cur的下一位
next = cur.next;
//将cur的下一个节点指向新的链表的最前端
cur.next = reverseHead.next;
//将cur链接到新的链表上
reverseHead.next = cur;
//让cur后移
cur = next;
}
//遍历结束,将head.next指向reverseHead.next 接管链表,实现单链表的反转
head.next = reverseHead.next;
}
}
不带头节点的链表
思路和前一种方式一样,不过理解起来比前面的难一点点~
public static ListNode reverseList(ListNode head) {
// 存储反转后的节点
ListNode prev = null;
// 临时变量,用于交换位置
ListNode next = null;
while(head !=null){
next = head.next; //保存下一个指针
head.next = prev; //将下一个指针指向上一个
prev = head; //新的链表
head = next; //指向新的链表头
}
return prev;
}