天天看點

JAVA手寫代碼連結清單反轉_資料結構List示例(一):連結清單反轉

鍊式存儲結構就是兩個相鄰的元素在記憶體中可能不是相鄰的,每一個元素都有一個指針域,指針域一般是存儲着到下一個元素的指針。這種存儲方式的優點是插入和删除的時間複雜度為O(1),不會浪費太多記憶體,添加元素的時候才會申請記憶體,删除元素會釋放記憶體,。缺點是通路的時間複雜度最壞為O(n),關于查找的算法很少,一般隻能周遊,這樣時間複雜度也是線性(O(n))的了,頻繁的申請和釋放記憶體也會消耗時間。

順序表的特性是随機讀取,也就是通路一個元素的時間複雜度是O(1),鍊式表的特性是插入和删除的時間複雜度為O(1)。要根據實際情況去選取适合自己的存儲結構。

連結清單就是鍊式存儲的線性表。根據指針域的不同,連結清單分為單向連結清單、雙向連結清單、循環連結清單等等。

連結清單反轉也是比較常見的問題,一般解決方式是:分别設定三個指針。第一個指針保持結果,第二個指針指向目前的節點,第三個指針儲存下一個節點。實作代碼如下:

    package List;    public class ListReverse {    public static class Node { public int data; public Node next;   public Node(int data) { this.data = data; this.next = null; } }    public static class LinkList { // 根結點 private Node root;    public void push(int data) { Node cur = root; if (root == null) { // 配置設定記憶體空間 root = new Node(data); return; } while (cur.next != null) { cur = cur.next; } // 配置設定記憶體空間 cur.next = new Node(data); }    public Node linkListReversre() { // 目前結點 Node cur = null; // 下一個結點 Node next = null; // 前一個結點 Node pre = null;   // 判斷邊界條件,空連結清單 if (root == null) { return null; } // 指派 cur = root; // 當連結清單非空時,執行反轉 while (cur != null) { // 儲存後一個結點 next = cur.next; // 注意此處反轉的順序不能亂 cur.next = pre; pre = cur; cur = next; } // 反轉結束後修改頭結點 root = pre; // 傳回 return root; }  public Node linkListRecReverse(Node cur){ // Node cur = root; if(cur == null || cur.next == null){ return cur; } //遞歸 Node reverseRest = linkListRecReverse(cur.next); //反轉 cur.next.next = cur; //源節點為空 cur.next = null; return reverseRest; }   public void printList() { Node cur = root; // 空表 if (root == null) { return; } // 非空 while (cur != null) { System.out.print(cur.data + " "); cur = cur.next; } } }      public static void main(String[] args) { // TODO Auto-generated method stub LinkList list = new LinkList(); //添加資料 list.push(10); list.push(2); list.push(3); list.push(4); list.push(5); list.push(6); //輸出原始連結清單 list.printList(); System.out.println(); //非遞歸反轉 list.linkListReversre(); //輸出原始連結清單 list.printList();  }   }