java用遞迴和非遞迴實現連結串列逆序
阿新 • • 發佈:2019-02-17
傳統的逆序連結串列方法是使用三個指標來記錄節點的狀態,防止連結串列斷裂。
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();
}