1. 程式人生 > >java實現連結串列反轉

java實現連結串列反轉

## 為什麼面試常考連結串列反轉 連結串列是常用的資料結構,同時也是面試常考點,連結串列為什麼常考,因為連結串列手寫時,大多都會有許多坑,比如在新增節點時因為順序不對的話會讓引用指向自己,因此會導致記憶體洩漏等問題,Java會有JVM管理記憶體,可能不會引起太大問題,如果是c、c++、c#,這些語言都需要手動釋放記憶體,如果操作不當後果不堪設想。其原因就是程式設計師對(引用)指標的理解出現偏差。 如果不瞭解Java引用可以檢視這篇部落格: > [你不知道的Java引用](https://www.cnblogs.com/glassysky/p/13385282.html) ## 怎樣實現連結串列反轉 翻轉連結串列實現如下: ```Java public class Link { Node head; public void reverse() { if (head.isEmpty() || head.next.isEmpty()) return; Node cur = head.next; Node pre = head; while (cur!=null) { Node tmp = cur.next; cur.next = pre; //變成了 cur-》pre-》源cur.next節點 head.next = tmp; //2->1->3 c:3 p:2 3->2->4(1節點直接被4覆蓋),需要修改 pre = cur; cur = tmp; tmp = null; //垃圾回收 } head = pre; } public boolean isEmpty() { return head == null; } } class Node { int val; Node next; public Node(int val) { this.val = val; next = null; } public boolean isEmpty() { return this == null; } @Override public String toString() { return "Node{" + "val=" + val + ", next=" + next + '}'; } } ``` 分析思路:   一般嘗試,如果直接while讓cur.next=cur;在cur.next=cur之前拿到cur.next的下一個節點,會出現子級指向自己的死環,這是不可取的。   換一個方法,如果多新增一個是否會有幫助,新增一個pre=head引用,讓cur移動一個單位,現在cur從head.next的位置,讓cur的下一個位置 儲存pre引用的地址,在cur的下一位置重新指向前事先讓pre指向cur.next節點 原始碼如下: ```Java while () { pre.next = cur.next; cur.next = pre; //變成了 cur-》pre-》源cur.next節點 Node tmp = pre; //2->1->3 c:3 p:2 3->2->4(1節點直接被4覆蓋),需要修改 pre = cur; cur = tmp; tmp = null; //垃圾回收 } ``` 很明顯,原始碼中並沒有未排序的部分新增到連結串列尾部,而是直接放到了pre節點的後邊,造成了汙染資料的後果,經過修改後就是上面帶實現類原始碼。   如果不明白為什麼是head.next=tmp;假如有一個連結串列是1->2->3->4,第一次翻轉時候都是讓cur放到pre的前面,再把沒有排序的部分放到後邊,如果第二次在按照這個思路跑的話,就會變成3->2->4,就會把原來2後邊的1覆蓋了,這裡就有問題了,後邊的節點不應該放到2後邊,而是應該放到1,這個1正好是原來連結串列的head節點,所以每次新增的位置應該是head後邊。 ## 最後結果 最後跑完的結果是: ```Java DEBUG: Node{val=4, next=Node{val=3, next=Node{val=2, next=Node{val=1, next=null}}