java实现单链表反转
导语:如果你打开了此网页说明你至少对链表或者说链表的结构有一个大概的了
解,那么什么是链表反转并且如何实现链表反转的呢?
链表反转的意思就是输入一个链表,反转链表后,输出新链表的头,换句话说就是原链表倒序输出。
实现链表反转有两种方法,即递归法链表反转和遍历法链表反转。这两种方法在我们面试的时候也是面试官比较爱问的一些基础。
接下来我们就介绍并且分析一下这两种方法:
遍历法
在链表遍历的过程中将指针顺序置换,如下图
代码实现如下:
public ListNode ReverseList(ListNode head) {
if(head==null){
return head;
}
ListNode pre = null;
ListNode next = null;
while(head!=null){
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
代码分析
1.首先是一个if语句对原链表进行判空操作,如果为空直接返回head
2.然后我们初始化两个变量,pre用来保存先前结点,next用来做临时变量
3.接下来就是最为关键的四行代码啦~,我以图解的方式让大家更好的明白
4.以原链表A -> B -> C -> D为例,实现D -> C -> B-> A
5.执行第一行代码 next = head.next -> next = 1结点.next(2结点)
将head.next赋给临时变量
6.执行第二行代码 head.next = pre -> 1结点.next = pre(null)
断开头结点
7.执行第三行代码 pre = head -> pre = 1结点
将头结点赋给pre,返回pre
8.执行第四行代码 head = next -> head = 2结点
将原链表头结点的下个结点设为新的头结点
9.到这里还没有完,按照如上步骤执行下一次循环
next = head.next;
head.next = pre;
pre = head;
head = next;
翻译就是:
10.之后按照这样一直循环就行啦…
递归法
递归法和遍历法可以说是正好相反,递归法是从最后一个结点开始,在弹栈的过程中将指针顺序置换的
代码实现如下:
public static class Node {
public int value;
public Node next;
public Node(int data) {
this.value = data;
}
}
//反转方法
public Node reverse(Node head) {
if (head == null || head.next == null)
return head;
Node temp = head.next;
Node newHead = reverse(head.next);
temp.next = head;
head.next = null;
return newHead;
}
代码分析
1.首先在类中先定义Node,初始化一个value(static会默认给变量属性赋值)
2.接下来是反转方法实现,首先对原链表进行判断是否为空或者只有头结点
3.接下来的四行代码也是最为关键的核心代码
4.以原链表A -> B -> C -> D为例,实现D -> C -> B-> A
5.程序到达Node newHead = reverse(head.next);时进入递归,假设此时递归到了C结点,此时head=C结点
6.递归到Node temp = head.next 也就是将C的下一个结点也就是D结点赋给temp
7.执行Node newHead = reverse(head.next);也就是传入的head.next是D结点,返回的newHead是D结点
8.接下里就是我们刚才所说的弹栈过程了,继续执行→
9.程序继续执行temp.next = head,也就是说D结点的下一个结点是刚才的头结点C
10.head.next = null 也就是把 3结点指向4结点的指针断掉
11.return之后,系统会恢复2结点压栈时的现场,此时的head=B结点;temp=B结点.next(C结点),再进行上述的操作(…C结点后边是B结点,将B结点指向C结点指针断掉…此处省略一个亿…)最后完成整个链表翻转
结语:到此单链表反转实现的两种方式就介绍完了,如果理解有误,还请各位走过路过的朋友加以指正,过了这个村我在下个村口等你…