快速找到未知長度單鏈表的中間節點
阿新 • • 發佈:2017-08-14
變量 div ride span 一個 ima list 方法 .com
在討論之前,我們首先首先要明白,什麽是單鏈表?
單鏈表:鏈接方式存儲的線性表
單鏈表的結點結構
┌──┬──┐
│data│next│
└──┴──┘
data域--存放結點值的數據域
next域--存放結點的直接後繼的地址(位置)的指針域(鏈域)
註意:
①鏈表通過每個結點的鏈域將線性表的n個結點按其邏輯順序鏈接在一起的。
②每個結點只有一個鏈域的鏈表稱為單鏈表(Single Linked List)。
那麽我們先用java設計一下我們的單鏈表
public class MyLinkedList<E> { Node<E> first;Node<E> last; public MyLinkedList() { super(); } public void add(E e) { if (first == null) { first = new Node<E>(e, null); } else { if (last == null) { last = new Node<E>(e, null); first.next= last;// 因為first和last還沒建立關系,所以在這裏要將他們的關系建立起來 } else { Node<E> n = new Node<>(e, null);// 一個臨時的引用n last.next = n;// 將last的next賦值為n的引用 last = n;// 然後再將last重新賦值為n的引用 } } } @Override public String toString() { StringBuilder sb= new StringBuilder(); sb.append("["); for (Node<E> n = first; n != null; n = n.next) { sb.append(n.item).append(","); } sb.deleteCharAt(sb.length()-1).append("]"); return sb.toString(); } private static class Node<E> { E item; Node<E> next; Node(E element, Node<E> next) { this.item = element; this.next = next; } } }
註意了,在這裏我設計的單鏈表僅僅是為了符合我們討論的問題,並不是完整的單鏈表,同時為了測試,我重寫了toString方法。在這個單鏈表裏面,我並沒有實現List<E>這個接口,因為要實現的方法太多了,而且first和last這兩個成員變量沒有用private修飾符修飾,是不符合封裝的思想,這裏我一切從簡。
我們先往裏面添加一些數值,順便測試下我們設計的單鏈表是否可以
public static void main(String[] args){ MyLinkedList<Integer> list=new MyLinkedList<>(); list.add(2); list.add(1); list.add(5); list.add(8); list.add(7); System.out.println(list.toString()); }
運行結果:
沒錯,我們設計的單鏈表沒問題
①快慢指針:一個指針每次按著順序跳兩次,而另一個指針只跳一次,當第一個指針跳到的元素為空是,那麽第二個指針就處於中間的位置
/** * 獲取中間元素 * * @return */ public E getMiddle() { Node<E> n1 = first;// 每次只走一步,慢指針 Node<E> n2 = first;// 每次走兩步,快指針 L: while (true) { if (n2.next != null && n2.next.next != null) { n1 = n1.next; n2 = n2.next.next; } else { break L; } } return n1.item; }
將上面的代碼添加到MyLinkedList.java裏面,測試
public static void main(String[] args){ MyLinkedList<Integer> list=new MyLinkedList<>(); list.add(2); list.add(1); list.add(5); list.add(8); list.add(7); System.out.println(list.toString()); System.out.println(list.getMiddle()); }
結果如下:
快速找到未知長度單鏈表的中間節點