单链表逆置-java(递归与非递归)
结点是一个自定义的类Node:
private class Node {
public int value;
public Node nextNode;
public Node(int value) {
this.value = value;
}
}
递归方法用的是栈的思想,先把头结点入栈,接着头结点的下一个结点入栈,直到尾结点位置,
接着依次把栈内的元素出栈,并更换其下一个结点对应的对象:
/**
* 逆置单链表(递归)
* @param head 头结点
* @return 逆置后的头结点
*/
private static Node revert(Node head) {
if (head == null || head.nextNode == null) {
// 到达尾结点
return head;
}
// 一直入栈
Node revertHead = revert(head.nextNode);
// 出栈并赋值nextNode对象
head.nextNode.nextNode = head;
head.nextNode = null;
// 返回尾结点(逆置后的头结点)
return revertHead;
}
非递归的方法其实就是顺着头结点往尾结点便利,遍历期间把每个结点的nextNode替换掉,
替换过程需要注意临时存储下一个结点:
/**
* 逆置单链表(非递归)
* @param head 头结点
* @return 逆置后的头结点
*/
private static Node revert2(Node head) {
Node pre = head;
Node cur = head.nextNode;
Node tmp;
// 头结点的nextNode应该要置空
pre.nextNode = null;
while (cur != null) {
// 先存放nex结点
tmp = cur.nextNode;
// 修改next结点指向pre
cur.nextNode = pre;
pre = cur;
cur = tmp;
}
return pre;
}
验证:
- 接着初始化一个单链表,
- 调用递归方式将链表逆置,并输出
- 调用非递归方式将链表再次逆置(还原到最初状态),并输出
代码如下:
Node head = new Node(0);
Node cur = null;
Node tmp;
for (int i = 1; i <= 10; i++) {
tmp = new Node(i);
if (i == 1) {
head.nextNode = tmp;
} else {
cur.nextNode = tmp;
}
cur = tmp;
}
// 递归方式
head = revert(head);
System.out.println("递归方式");
printNodes(head);
// 循环方式
head = revert2(head);
System.out.println("循环方式");
printNodes(head);
其中printNodes是输出方法:
private static void printNodes(Node head) {
System.out.print(head.value + "\t");
while (head.nextNode != null) {
System.out.print(head.nextNode.value + "\t");
head = head.nextNode;
}
System.out.println();
}
输出结果: