传统的逆序链表方法是使用三个指针来记录节点的状态,防止链表断裂。
Node节点
public class Node { private int data; private Node next; public Node(int data){ this.data = data; next = null; } public int getData() { return this.data; } public void setData(int data) { this.data = data; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } }
逆序方法
public static Node reverseLinkList(Node head){ Node p1=head,p2 = head.getNext(); Node p3=null; while (p2!=null){ p3 = p2.getNext(); p2.setNext(p1); p1 = p2; p2 = p3; } return p1; }
主方法里面逆序
Node newHead = reverseLinkList(head); head.setNext(null); p = newHead; while (p != null) { System.out.print(p.getData() + " "); p = p.getNext(); }
我在想递归是先处理好后面的问题,然后把结果返回。如果我从最后开始逆序整个链表,我获得当前节点的后一个节点的时候,当前节点的后面已经完成逆序。只要将后一个节点指向当前节点。
这里使用了静态变量newHead是因为要记录旧的尾节点来作为新的头节点。不然整个函数获得的只是旧的头结点(新的尾节点)。如果将newHead作为形参传入方法,而不设置成静态变量,是不行的。因为java里面对象的引用形参相当于拷贝了一份实参。直接改变形参指向一个新的对象是不会改变实参的。而改变形参引用的内容却可以改变实参所引用对象的内容,如下面的setNext方法。
private static Node newHead; public static Node getNextNode(Node node) { if (node.getNext() != null) { //获得后一个节点,此时该节点后面节点已经全部逆序完 Node nextNode = getNextNode(node.getNext()); nextNode.setNext(node); return node; } //最后一个节点 else { newHead = node; return node; } }
主方法里面调用,可以发现递归来实现逆序也是可以的
Node tail = getNextNode(head); //尾节点(原头节点)指向null tail.setNext(null); p = newHead; while (p != null) { System.out.print(p.getData() + " "); p = p.getNext(); }