Java 简单实现单向链表反转
链表反转代码
package main; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import java.util.Objects; import java.util.Optional; import java.util.concurrent.CountDownLatch; @Getter @Setter @NoArgsConstructor class Node { private Node next; private Node head; private int value; public Node(Node next, int value) { this.next = next; this.value = value; } public void addNode(int value) { Node headTemp = head; Node newNode = new Node(null, value); Optional.ofNullable(headTemp).ifPresentOrElse(r -> { Node tempNode = headTemp; while (Objects.nonNull(tempNode.getNext())) { tempNode = tempNode.getNext(); } tempNode.setNext(newNode); }, () -> { System.out.println(">>>>>>>这个虽然是 Runnable,但是确实同步方法..."); head = newNode; }); } public void iterator(Node headNode) { Optional.ofNullable(headNode).ifPresent(r -> { Node headTemp = headNode; while (headTemp != null) { System.out.println(headTemp.value); headTemp = headTemp.getNext(); } }); } public Node reverseLinked(Node headNode) { if (Objects.isNull(headNode) || Objects.isNull(headNode.getNext())) { return headNode; } // 临时变量,可以理解为反转后的头结点 Node reverseNode = null; while (headNode != null) { // 1-->2-->3 => 3-->2-->1 Node nextNode = headNode.getNext(); // 建立 next 指向 headNode.setNext(reverseNode); // 首节点往后移动,移动到节点 3 即可 reverseNode = headNode; // 迭代遍历指针后移 headNode = nextNode; } return reverseNode; } } public class ReverseLinked { public static void main(String[] args) throws InterruptedException { Node node = new Node(); node.addNode(1); node.addNode(2); node.addNode(3); node.addNode(4); node.iterator(node.getHead()); System.out.println("链表反转后------------"); Node newHead = node.reverseLinked(node.getHead()); node.iterator(newHead); } }
输出结果:
>>>>>>>这个虽然是 Runnable,但是确实同步方法... 1 2 3 4 链表反转后------------ 4 3 2 1
需要注意的是 ifPresentOrElse() 方法源码如下:
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) { if (value != null) { action.accept(value); } else { emptyAction.run(); } }
第二个参数虽然是个 Runnable,但是采用的还是同步方法调用,直接自己调用 run() 方法,所以这段逻辑执行还是在同一个线程执行,并没有开启异步线程。
reverseLinked 反转方法演示
public Node reverseLinked(Node headNode) { if (Objects.isNull(headNode) || Objects.isNull(headNode.getNext())) { return headNode; } // 临时变量,可以理解为反转后的头结点 Node reverseNode = null; while (headNode != null) { // 1-->2-->3 => 3-->2-->1 Node nextNode = headNode.getNext(); // 建立 next 指向 headNode.setNext(reverseNode); // 首节点往后移动,移动到节点 3 即可 reverseNode = headNode; // 迭代遍历指针后移 headNode = nextNode; } return reverseNode; }
流程图如下:
总结:先从原来的头结点开始遍历,然后将后一个节点的指向,指向前一个节点,临时变量记录着遍历到最后的一个节点,这最后一个节点也就是新链表的首节点。