目錄node
「數組」做爲數據存儲結構有必定的缺陷數組
無論在哪一種數組中刪除效率都很低,建立數組後,大小不可改變數據結構
鏈表 LinkedListapp
數據儲存在「節點(Node)」中,一個鏈節點是某個類的對象ide
優勢:真正的動態,不須要處理固定容量的問題(不用像數組new出來一片空間)this
缺點:不能隨機訪問(數組開闢的空間在內存上是連續的,能夠經過下標計算出內存地址進行隨機訪問,而鏈表必須是順序訪問,因爲依靠next一層一層鏈接,在計算機的底層,每個節點對應的內存地址不一樣)spa
數組:最好用於索引有語意的狀況(user[1])3d
優勢:快速查詢指針
數組:最好不用於索引有語意的狀況code
鏈表:動態
在數組中,在最後面添加元素是最方便的,由於有size在跟蹤數組的最後一個元素
可是鏈表偏偏相反,鏈表頭添加元素,由於有head頭結點,沒有跟蹤最後一個元素的結點
public class LinkedList<E>{ 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); } } private Node head; private int size; public LinkedList(){ head=null; size=0; } //獲取鏈表中元素個數 public int getSize() { return size; } public boolean isEmpty(){ return size==0; } //在鏈表頭結點添加元素 public void addFirst(E e){ Node node=new Node(e); node.next=head; head=node; //head=new Node(e);至關於上面三行 size++; } }
在搜索爲2的位置插入元素
關鍵:找到添加結點的前一個節點
注意:如插入到索引爲0的節點後面,頭結點沒有前驅節點
//在鏈表中間添加元素 public void add(int index,E e){ //判斷索引的和發現 if(index<0||index>size){ throw new IllegalArgumentException("add failed,illegal index"); } //若是在鏈表頭添加,因爲鏈表頭沒有前驅節點,需特殊處理 if(index==0){ addFirst(e); }else{ Node pre=head; for (int i = 0; i <index-1 ; i++) { //一直將前驅節點向前移,直到找到index位置的節點 pre=pre.next; Node node=new Node(e); node.next=pre.next; pre.next=node; //pre.next=new Node(e,pre.next);至關於上面三行 size++; } } } //在鏈表末尾添加元素 public void addLast(E e){ add(size,e); }
因爲頭結點沒有前驅節點,在鏈表頭結點和其餘位置插入元素,會有所不一樣
所以構建一個虛擬頭結點爲null,就不須要對頭結點進行特殊處理,只須要找到待添加元素的前一個節點
//在鏈表中間添加元素 public void add(int index,E e){ //判斷索引的和發現 if(index<0||index>size){ throw new IllegalArgumentException("add failed,illegal index"); } //若是在鏈表頭添加,因爲鏈表頭沒有前驅節點,需特殊處理 Node pre=dummyHead; for (int i = 0; i <index; i++) { //一直將前驅節點向前移,直到找到index位置的節點 pre=pre.next; Node node=new Node(e); node.next=pre.next; pre.next=node; //pre.next=new Node(e,pre.next);至關於上面三行 size++; } } //在鏈表末尾添加元素 public void addLast(E e){ add(size,e); } //在鏈表頭結點添加元素 public void addFirst(E e){ add(0,e); }
四、鏈表
//得到鏈表的第index(0-base)個位置的元素 public E get(int index){ //判斷索引的合法性 if(index<0||index>size){ throw new IllegalArgumentException("add failed,illegal index"); } Node cur=dummyHead.next; for (int i = 0; i <index ; i++) { cur=cur.next; } return cur.e; } //獲取鏈表第一個元素 public E getFirst(){ return get(0); } public E getLast(){ return get(size-1); }