Java實現雙鏈表的具體實現加註釋
阿新 • • 發佈:2018-12-19
雙向迴圈連結串列的節點裡麵包含前指標prev,指向下一個節點的指標next,和節點內容data。因為指向讓使用者去操作最外邊的測試程式,所以使用者不用知道有節點的存在,因此把節點設定為內部類。
首先用一個介面區羅列要實現的功能,主要包括增加節點,刪除節點,判斷該節點是否存在,判斷連結串列的大小,判斷連結串列是否為空,獲取連結串列的內容等
interface ILink{//定義介面 /** * 插入節點, * @param obj Object可以接收一切物件 */ void add(Object obj); /** * //刪除節點,用布林值返回是否刪除成功, * @param obj 要刪除的節點 * @return 1成功,0失敗、 */ boolean remove(Object obj); /** * 修改指定位置的內容 * @param index 指定位置 * @param newData 新節點的內容 * @return 返回之前節點的內容 */ Object set(int index,Object newData); /** * 獲取指定節點的內容 * @param index 指定節點 * @return 節點內容 */ Object get(int index); /** * 判斷連結串列中是否穿在該節點 * @param data 節點內容 * @return 返回-表示不存在該節點 */ int contains(Object data); /** * 求連結串列的大小 * @return 返回連結串列的長度 */ int size(); /** * 清空連結串列 */ void clear(); /** * 將連結串列轉化為陣列 * @return 返回節點內容陣列 */ Object[] toArray(); /** * 列印連結串列 */ void print(); }
定義一個類去實現接口裡面的具體功能。各個函式的具體實現以及實現原理都在程式碼後邊備註了。
class LinkImpl implements ILink{//定義一個類 ,繼承介面,並實現它 private Node head; private Node last; private int size; private class Node{//定義節點對外部不可見 private Node prev; private Node next; private Object data; public Node(Node prev,Node next,Object data){ this.prev=prev; this.next=next; this.data=data; } } @Override public void add(Object obj){ Node temp=this.last;//讓temp指向最後一個節點 //讓新節點的prev指向最後一個節點,讓next指標為null,把新增的節點內容obj給data Node newNode=new Node(temp,null,obj); this.last=newNode;//讓最後一個指標指向newNode if(this.head==null){//判斷頭結點是否為空 this.head=newNode;//為空,頭結點節等於新節點 }else{//不為空,temp的下一個節點等於新節點 temp.next=newNode; } this.size++;//連結串列的大小加一 } @Override public boolean remove(Object obj) { if(obj==null){//如果輸出物件為空 for(Node temp=head;temp!=null;temp=temp.next){ if(temp.data==null){//找到內容為空的物件 unLink(temp);//刪除物件 return true; } } }else{//刪除內容不為空 for(Node temp=head;temp!=null;temp=temp.next){ if(obj.equals(temp.data)){//判斷刪除內容個和連結串列內容是否一致 unLink(temp);//刪除物件 return true;//刪除成功 } } } return false;//刪除失敗 } @Override public Object set(int index, Object newData) { if(!isLinkIndex(index)){//判斷節點是否存在,不存在返回null return null; } Object element=node(index).data;//獲取該節點的內容 node(index).data=newData;//更改 節點的內容 return element;//返回更改前的節點 } @Override public Object get(int index) { if(!isLinkIndex(index)){//判斷節點是否存在,不存在返回null return null; } return node(index).data;//節點存在返回他的內容 } @Override public int contains(Object data) { int i=0; if(data==null){//當data等於空時,直接遍歷一遍看看裡面有沒有data==null for(Node temp=head;temp!=null;temp=temp.next){ if(temp.data==null){//找到temp.data等於null是返回i return i; } i++;//繼續向後尋找 } }else{//data不等於空時 for(Node temp=head;temp!=null;temp=temp.next){ if(data.equals(temp.data)){//用equals方法判斷內容是否相等 return i;//相等返回i } i++; } } return -1;//不存在返回-1 } @Override public int size() { return this.size;//this表示呼叫當前物件 } @Override public void clear() { for(Node temp=head;temp!=null;){ Node flag=temp.next;//提前儲存下一個節點 temp.prev=temp=temp.next=null;//讓節點的三個部分都為null temp=flag;//讓temp等於下一個節點 this.size--;//清空一個節點連結串列的大小減一 } } @Override public Object[] toArray() { Object[] result=new Object[size];//定義一個物件陣列 int i=0; for(Node temp=head;temp!=null;temp=temp.next){ //定義一個temp等於頭節點,區便利連結串列 result[i++]=temp.data;//把temp的值給物件陣列 } return result;//返回物件陣列 } @Override public void print() { Object[] data =this.toArray(); for(Object temp:data){//foreach迴圈輸出內容 System.out.println(temp); } } private boolean isLinkIndex(int index){ //判斷這個節點是否在這個連結串列裡 return index>=0&&index<size; } private Node node(int index){//在連結串列中找這個節點,並返回該節點 if(index<(size>>1)){//判斷這個節點是否在前半部分 Node temp=head; for(int i=0;i<index;i++){ temp=temp.next;//向後迴圈直到等於index } return temp; } Node temp=this.last;//節點在後半部分 for(int i=size-1;i>index;i--){//節點從最後一個向前數,到index時停止 temp=temp.prev;//向前迴圈直到等於index } return temp; } private void unLink(Node node){//刪除節點 Node prev =node.prev; Node next=node.next; if(prev==null){//刪除頭結點 this.head=next;//讓head等於next }else{ prev.next=next;//讓前一個指標的next指向下一個節點 node.prev=null;//讓前節點的prev=null } if(next==null){//刪除尾節點 this.last=prev;//讓他的尾節點等於他前一個節點 }else{ next.prev=prev;//next的前指標prev等於前一個節點 node.next=null;//讓node 的下一個節點為空 } node.data=null;//把節點的內容置空 this.size--;//連結串列的大小減一 } }
測試函式
public class Link { public static void main(String[] agrs){ ILink link = new LinkImpl(); link.add("火車頭"); link.add("車廂1"); link.add("車廂2"); link.add(null); link.add("車廂尾"); link.print(); System.out.println(); link.remove("火車頭"); link.print(); System.out.println(); link.remove("車廂尾"); link.print(); System.out.println(); link.remove(null); link.remove("哈哈哈"); link.print(); } }