思路:
设置两个引用,一个为新链表的头结点,一个为遍历原链表的当前节点,遍历一次后,即可反转链表。
代码实现:
package com.datastructure.link;
import java.util.Stack;
/*
* 数据结构之单链表
*/
public class SingleLinkedList
{
/*
* 元素的基本定义
*/
static class Node{
/*
* value
*/
private int value;
/*
* 链表的下一个元素
*/
private Node next;
public Node (int value) {
this.value = value;
}
@Override
public String toString() {
if (this.next == null) {
return String.valueOf(this.value);
}
return this.value + "->" + this.next.toString();
}
}
/*
* 反转单链表
*
* 思路:遍历链表,把元素压入栈中,利用栈后进先出特性,遍历栈中元素,重组链表实现翻转
*
* 分析:此方式简单易行,但是需要额外空间,需要遍历两次(一次链表+一次栈遍历)
*/
public static Node reverseLinkedListByStack(Node node) {
// 1、判空
if (node == null) {
return null;
}
// 2、链表元素压入栈中
Node curNode = node;
Stack<Node> stack = new Stack<>();
while (curNode != null) {
stack.push(curNode);
curNode = curNode.next;
}
// 3、重组新链表
Node newNode = stack.pop();
// 遍历方案1
/*
Node tmpNode = newNode;
while (!stack.isEmpty()) {
Node curPopNode = stack.pop();
tmpNode.next = curPopNode;
tmpNode = curPopNode;
}
tmpNode.next = null;
*/
// 遍历方案2
///*
while(!stack.isEmpty()) {
Node curPopNode = stack.pop();
curPopNode.next.next = curPopNode;
curPopNode.next = null;
}
//*/
return newNode;
}
/*
* 反转单链表优化方案,只需遍历一次,遍历时拆开链表,当前元素指向前一个元素
*/
public static Node reverseLinkedList(Node node) {
if (node == null) {
return null;
}
Node newNode = null;
Node tmpNode = node;
while (tmpNode != null) {
// 缓存下一个节点便于while循环
Node nextNode = tmpNode.next;
// 改变当前遍历节点的指向
tmpNode.next = newNode;
// 推进新链表的头结点
newNode = tmpNode;
// while条件前移
tmpNode = nextNode;
}
return newNode;
}
public static void main(String args[]) {
// 原链表
System.out.println("Origin link: " + createTestLinkedList());
// 反转链表
System.out.println("link reverse: " + reverseLinkedList(createTestLinkedList()));
}
private static Node createTestLinkedList() {
Node head = new Node(0);
Node curNode = head;
for (int i = 1; i < 10; i++) {
curNode.next = new Node(i);
curNode = curNode.next;
}
return head;
}
}