java實現鏈表反轉


為什么面試常考鏈表反轉

鏈表是常用的數據結構,同時也是面試常考點,鏈表為什么常考,因為鏈表手寫時,大多都會有許多坑,比如在添加節點時因為順序不對的話會讓引用指向自己,因此會導致內存泄漏等問題,Java會有JVM管理內存,可能不會引起太大問題,如果是c、c++、c#,這些語言都需要手動釋放內存,如果操作不當后果不堪設想。其原因就是程序員對(引用)指針的理解出現偏差。

如果不了解Java引用可以查看這篇博客:

你不知道的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節點
源碼如下:

    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后邊。

最后結果

最后跑完的結果是:

DEBUG:
  Node{val=4, next=Node{val=3, next=Node{val=2, next=Node{val=1, next=null}}}}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM