在瞭解單鏈表以前,你知道什麼是鏈表嗎?若是你不知道什麼是鏈表,能夠看看個人這篇博客<鏈表-LinkList>html
單鏈表是鏈表的其中一種基本結構。一個最簡單的結點結構如圖所示,它是構成單鏈表的基本結點結構。在結點中數據域用來存儲數據元素,指針域用於指向下一個具備相同結構的結點。
由於只有一個指針結點,稱爲單鏈表。java
單鏈表中三個概念須要區分清楚:分別是頭指針,頭節點和首元節點。node
若頭結點的指針域爲空(NULL),代表鏈表是空表。頭結點對於鏈表來講,不是必須的,在處理某些問題時,給鏈表添加頭結點會使問題變得簡單。
首元結點:鏈表中第一個元素所在的結點,它是頭結點後邊的第一個結點。this
頭指針:永遠指向鏈表中第一個結點的位置(若是鏈表有頭結點,頭指針指向頭結點;不然,頭指針指向首元結點)。指針
頭結點和頭指針的區別:頭指針是一個指針,頭指針指向鏈表的頭結點或者首元結點;頭結點是一個實際存在的結點,它包含有數據域和指針域。二者在程序中的直接體現就是:頭指針只聲明而沒有分配存儲空間,頭結點進行了聲明並分配了一個結點的實際物理內存。code
單鏈表中能夠沒有頭結點,可是不能沒有頭指針!
頭節點的引入能使鏈表對第一個元素的刪除和插入和其餘元素相同,不用另外說明,使得代碼更加簡潔。htm
單鏈表的基本操做有:增(add),刪(remove),改(set),查(find),插(insert)等。blog
在這裏咱們只講解add,remove,insert三個操做,其餘實現看源碼。內存
聲明一個新節點node做爲新的尾節點,next=null;ci
獲取原鏈表的最後一個節點,把它的next指向1步驟的新節點node
public void add(AnyType a){ Node<AnyType> renode=new Node<>(a,null); getNode(thesize-1).next=renode; thesize++; }
獲取須要刪除的節點的上一個節點node
把node的next指向node的next的next
由於node的next節點沒有指針指向它,所以它會被系統自動清理
public AnyType remove(int i){ Node<AnyType> prev=getNode(i-1); AnyType a=prev.next.data; prev.next=prev.next.next; thesize--; return a; }
獲取須要插入的位置的節點;
聲明一個新節點node指向1步驟獲得的節點;
獲取須要插入位置節點的上一個節點;
將3步驟獲得的節點的next指向新節點node;
public void insert(int i,AnyType a){ Node<AnyType> prev=getNode(i-1); Node<AnyType> renode=new Node<>(a,prev.next); prev.next=renode; thesize++; }
/* 結點 */ public class Node<AnyType> { public AnyType data; public Node<AnyType> next; public Node(AnyType data,Node<AnyType> next){ this.data=data; this.next=next; } } ----- public class MyLinkList<AnyType> { //首元節點 private Node<AnyType> first; //頭指針 private Node<AnyType> head; //鏈表長度 int thesize; //初始化鏈表 public boolean initlist(){ thesize=0; first=new Node<>(null,null); head=new Node<>(null,first); return true; } //判斷鏈表是否爲空 public boolean isEmpty(){ return thesize==0; } //獲取節點 public Node<AnyType> getNode(int i){ Node<AnyType> renode=head; for(int j=-2;j<i;j++){ renode=renode.next; } return renode; } //在末尾添加元素 public void add(AnyType a){ Node<AnyType> renode=new Node<>(a,null); getNode(thesize-1).next=renode; thesize++; } //刪除i位置節點,並返回刪掉的數據 public AnyType remove(int i){ if(i==thesize-1){ AnyType a=getNode(thesize-1).data; getNode(thesize-2).next=null; return a; } Node<AnyType> prev=getNode(i-1); AnyType a=prev.next.data; prev.next=prev.next.next; thesize--; return a; } //在i位置插入新節點 public void insert(int i,AnyType a){ Node<AnyType> prev=getNode(i-1); Node<AnyType> renode=new Node<>(a,prev.next); prev.next=renode; thesize++; } //獲取i位置節點的數據 public AnyType get(int i){ return getNode(i).data; } //爲i位置元素從新賦值 public void set(int i,AnyType a){ getNode(i).data=a; } //返回鏈表節點個數 public int length(){ return thesize; } //清空鏈表 public void clear(){ initlist(); } //打印鏈表 public void print(){ for(int i=0;i<thesize;i++){ System.out.println(getNode(i).data); } } }