自定義連結串列(1)
阿新 • • 發佈:2019-01-03
通過學習自定義連結串列,瞭解連結串列的資料結構。
首先寫一個連結串列類 :LinkedList.java
最後,測試: Test.java、
知識點:
1.連結串列的內部維護了一個節點Node類。該類包括資料域和指標域(指標域指向下一個Node節點)
2.通常需要一個虛擬頭結點,但不是必須的。
結構:
LinkedList.java:
package LinkedList; public class LinkedList <E>{ /** * 維護的一個內部類,描述節點資訊 * @author Xiaohua * */ private class Node{ public E e;//資料域 public Node next;//指標域 public Node(E e, Node next) { this.e=e; this.next=next; } public Node(E e) { this(e,null); } public Node() { this(null,null); } @Override public String toString() { return e.toString(); } } private Node dummyHead;//虛擬頭結點 private int size;//連結串列大小 /** * 無參建構函式,初始化一個虛擬頭結點,資料域、指標域都為null。 */ public LinkedList() { dummyHead=new Node(); size=0; } /** * 獲取連結串列中元素個數 * @return */ public int getSize() { return size; } /** * 判斷連結串列是否為空 * @return */ public boolean isEmpty() { return size==0; } /** * 在連結串列的指定位置新增元素 * (不是常用操作,練習用) * pre的作用:找到要插入索引位置的前一個Node節點 * @param index * @param e */ public void add(int index,E e) { if(index < 0 || index > size) { throw new IllegalArgumentException("新增失敗,不合法的索引值"); } Node pre=dummyHead; for(int i=0;i<index;i++) { pre=pre.next; } Node node=new Node(e); node.next=pre.next; pre.next=node; //以上3句等價於這1句: //pre.next = new Node(e, pre.next); size++; } /** * 在連結串列頭部新增元素 * @param e */ public void addFirst(E e) { add(0,e); } /** * 在連結串列尾部新增元素 * @param e */ public void addLast(E e) { add(size,e); } /** * 獲取連結串列指定索引的元素 * (不是常用操作,練習用) * cur的作用:代表當前指向的Node節點。 * @param index * @return */ public E get(int index) { if(index < 0 || index >= size) { throw new IllegalArgumentException("獲取失敗,不合格索引。"); } Node cur=dummyHead.next; for(int i=0;i<index;i++) { cur=cur.next; } return cur.e; } /** * 獲得連結串列的第一個元素 * @return */ public E getFirst() { return get(0); } /** * 獲得連結串列的最後一個元素 * @return */ public E getLast() { return get(size-1); } /** * 修改連結串列的指定索引的值。 * (不是常用操作,練習用) * @param index * @param e */ public void set(int index,E e) { if(index < 0 || index >= size) { throw new IllegalArgumentException("設定失敗,不合法索引."); } Node cur=dummyHead.next; for(int i=0;i<index;i++) { cur=cur.next; } cur.e=e; } /** * 判斷連結串列中是否含有指定元素。 * @param e * @return */ public boolean contains(E e) { Node cur=dummyHead.next; while(cur!=null) { if(cur.e.equals(e)) { return true; } cur=cur.next; } return false; } /** * 刪除指定索引位置的元素,並返回。 * (不是常用操作,練習用) * @param index * @return */ public E remove(int index) { if(index < 0 || index >= size) { throw new IllegalArgumentException("刪除失敗,不合法索引."); } Node pre=dummyHead; for(int i=0;i<index;i++) { pre=pre.next; } Node ret=pre.next; pre.next=ret.next; ret.next=null; size--; return ret.e; } /** * 從連結串列中刪除第一個元素, 返回刪除的元素 * @return */ public E removeFirst(){ return remove(0); } /** * 從連結串列中刪除最後一個元素, 返回刪除的元素 * @return */ public E removeLast(){ return remove(size - 1); } /** * 從連結串列刪除指定元素 * @param e */ public void removeElement(E e) { Node pre=dummyHead; while(pre.next!=null) { if(pre.next.e.equals(e)) { break; } pre=pre.next; } if(pre.next!=null) { Node delNode=pre.next; pre.next=delNode.next; delNode.next=null; size--; } } /** * 重寫Object的toString方法 */ public String toString() { StringBuilder sb=new StringBuilder(); Node cur=dummyHead.next; while(cur!=null) { sb.append(cur+"-->"); cur=cur.next; } sb.append("null"); return sb.toString(); } }
Test.java:
package LinkedList; public class Test { public static void main(String[] args) { LinkedList<Integer> linkedList = new LinkedList<>(); for(int i = 0 ; i < 5 ; i ++){ linkedList.addFirst(i); System.out.println(linkedList); } linkedList.add(2, 666); System.out.println(linkedList); linkedList.remove(2); System.out.println(linkedList); linkedList.removeFirst(); System.out.println(linkedList); linkedList.removeLast(); System.out.println(linkedList); } }
控制檯輸出結果;