一、單鏈表的建立和遍歷:html
1java 2node 3面試 4app 5ide 6測試 7ui 8this 9spa 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
|
上方代碼中,這裏面的Node節點採用的是內部類來表示(33行)。使用內部類的最大好處是能夠和外部類進行私有操做的互相訪問。
注:內部類訪問的特色是:內部類能夠直接訪問外部類的成員,包括私有;外部類要訪問內部類的成員,必須先建立對象。
爲了方便添加和遍歷的操做,在LinkList類中添加一個成員變量current,用來表示當前節點的索引(03行)。
這裏面的遍歷鏈表的方法(20行)中,參數node表示從node節點開始遍歷,不必定要從head節點遍歷。
二、求單鏈表中節點的個數:
注意檢查鏈表是否爲空。時間複雜度爲O(n)。這個比較簡單。
核心代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
四、查找單鏈表中的中間結點:
一樣,面試官不容許你算出鏈表的長度,該怎麼作呢?
思路:
和上面的第2節同樣,也是設置兩個指針first和second,只不過這裏是,兩個指針同時向前走,second指針每次走兩步,first指針每次走 一步,直到second指針走到最後一個結點時,此時first指針所指的結點就是中間結點。注意鏈表爲空,鏈表結點個數爲1和2的狀況。時間複雜度爲 O(n)。
代碼實現:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
上方代碼中,當n爲偶數時,獲得的中間結點是第n/2 + 1個結點。好比鏈表有6個節點時,獲得的是第4個節點。
判斷單鏈表是否有環:
這裏也是用到兩個指針,若是一個鏈表有環,那麼用一個指針去遍歷,是永遠走不到頭的。
所以,咱們用兩個指針去遍歷:first指針每次走一步,second指針每次走兩步,若是first指針和second指針相遇,說明有環。時間複雜度爲O (n)。
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
完整版代碼:(包含測試部分)
這裏,咱們還須要加一個重載的add(Node node)方法,在建立單向循環鏈表時要用到。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
|
檢測單鏈表是否有環的代碼是第50行。
88行:咱們將頭結點繼續往鏈表中添加,此時單鏈表就環了。最終運行效果爲true。
若是刪掉了88行代碼,此時單鏈表沒有環,運行效果爲false。
取出有環鏈表中,環的長度:
咱們平時碰到的有環鏈表是下面的這種:(圖1)
上圖中環的長度是4。
但有可能也是下面的這種:(圖2)
此時,上圖中環的長度就是3了。
那怎麼求出環的長度呢?
|
完整版代碼:(包含測試部分)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
|
運行效果:
若是將上面的104至122行的測試代碼改爲下面這樣的:(即:將圖2中的結構改爲圖1中的結構)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
運行結果:
若是把上面的代碼中的第8行刪掉,那麼這個鏈表就沒有環了,因而運行的結果爲0。
一,問題描述
請本身構造一個簡單的有序單鏈表,而後實現刪除鏈表中的重複結點。好比:
二,問題分析
首先要實現一個單鏈表,所以須要定義一個節點類Node。其次,實現向鏈表中添加結點的方法(使用尾插法)addNode
刪除重複結點的實現思路:
定義兩個指針:pre 和 next。初始時,pre指向鏈表中的第一個元素,next指向鏈表中的第二個元素。若是 pre 的值與 next 的值不相等,則兩個指針分別都向後移一個結點;若相等,則刪除 next 指針指向的結點便可。
三,整個代碼實現
// delete duplicated nodes in increased list public class MyLinkedList { private class Node{ int ele; Node next; public Node(int ele) { this.ele = ele; next = null; } } private Node head; private Node tail; //採用尾插法添加結點 public void addNode(int ele){ Node newNode = new Node(ele); if(tail != null) tail.next = newNode; else{// first node head = newNode; } tail = newNode; } //刪除有序單鏈表中的重複結點 public void delDuplicatedNode(){ if(head == null) return; Node pre,next; pre = head; next = head.next; while(next != null) { if(pre.ele != next.ele) { pre = next; next = next.next; }else{//delete next point node Node delNode = next; pre.next = next.next; next = next.next; delNode.next = null;//avoid memory leak // delNode = null; } } } @Override public String toString() { if(head == null) return "null"; Node current = head; StringBuilder sb = new StringBuilder(); while(current != null){ sb.append(current.ele + " "); current = current.next; } return sb.toString(); } //hapjin test public static void main(String[] args) { MyLinkedList mylist = new MyLinkedList(); int[] eles = {1,2,3,3,4,4,5}; for (int ele : eles) { mylist.addNode(ele); } System.out.println("before del: " + mylist); mylist.delDuplicatedNode(); System.out.println("after del: " + mylist); } }