java实现单向链表
生活随笔
收集整理的這篇文章主要介紹了
java实现单向链表
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、單向鏈表的結(jié)構(gòu)。(1)、首先節(jié)點的結(jié)構(gòu),其中包含本節(jié)點內(nèi)容,以及需要指向下一個節(jié)點。 Java代碼
private static class Entry<E>{ E e; Entry<E> nextEntry; public Entry(E e,Entry<E> nextEntry){ this.e=e; this.nextEntry=nextEntry; } } private static class Entry<E>{E e;Entry<E> nextEntry;public Entry(E e,Entry<E> nextEntry){this.e=e;this.nextEntry=nextEntry;}}Java代碼 Java代碼 其中e則指向本節(jié)點的對象,而nextEntry則指向下一個節(jié)點。(2)、任何時候都需要知道表頭在哪里。畢竟是單向鏈表嘛,因為只有一個方向,找到了表頭就能找到全部。 Java代碼
private Entry<E> head; private Entry<E> head; (3)、還可以記錄鏈表中總共有多少個節(jié)點。它是在某些判斷時為了提高效率而存在的。不是絕對需要的。畢竟知道表頭后,一個一個按順序去尋找就好了。Java代碼
private int size; public int size(){ return this.size; } private int size;public int size(){return this.size;}
Java代碼 好了有這三樣,就足夠了。就看我們?nèi)绾斡盟麄兞恕6?nèi)部實現(xiàn)。(1)、第一次向鏈表中插入。此時鏈表中節(jié)點為null,第一次插入,無非就是把節(jié)點頭插入而已。 可以看出就是把鏈表頭初始化了,并且鏈表大小漲1。其中modCount記錄整個鏈表修改的次數(shù),鏈表的增加和刪除它都會增加。畢竟第一次插入相對外調(diào)用是透明的,所以應(yīng)該是私有的咯。(透明就是不可見,這里只得是外部沒必要知道它的存在)Java代碼
private void addFirst(E e){ head=new Entry<E>(e,null); size++; modCount++; } private void addFirst(E e){head=new Entry<E>(e,null);size++;modCount++;} (2)、表頭插入。在鏈表的頭前插入一個元素,新增的元素變成新的表頭。這個插入是效率最高的,畢竟你時刻知道鏈表的頭在哪里。Java代碼
public void addHead(E e){ if(head==null){ this.addFirst(e); }else{ Entry<E> newEntry=new Entry<E>(e,head); head=newEntry; size++; modCount++; } } public void addHead(E e){if(head==null){this.addFirst(e);}else{Entry<E> newEntry=new Entry<E>(e,head);head=newEntry;size++;modCount++;}}可以看出頭為null的時候,則表明鏈表中沒值,只需調(diào)用第一次插入。否則對給定的元素創(chuàng)新增一個節(jié)點,新增節(jié)點的下一個指向頭節(jié)點,當(dāng)然此時自己已經(jīng)變成頭結(jié)點了,索引要更新頭節(jié)點的引用。(可以看出想要清空鏈表,只需要將頭置為null就好了)(3)、指定節(jié)點插入(插隊)。在鏈表的指定節(jié)點插入一個元素,效率非常低。由于規(guī)則上你只能從隊伍第一個開始往后找,找到你要插隊位置的前一個,并將你插入其中,你先要告訴你身前人你在他身后,并且你自己要清楚你身后是誰。反正夠麻煩的。Java代碼
public void addSpecifyIndex(E e,int index){ if(index<0||index>size||size==0){ throw new NoSuchElementException(); } if(index==0){ this.addHead(e); return; } int count=0; for (Entry<E> p=head; p!=null;p=p.nextEntry) { if(count+1==index){ Entry<E> newEntry=new Entry<E>(e,p.nextEntry); p.nextEntry=newEntry; size++; modCount++; return; } count++; } } public void addSpecifyIndex(E e,int index){if(index<0||index>size||size==0){throw new NoSuchElementException();}if(index==0){this.addHead(e);return;}int count=0;for (Entry<E> p=head; p!=null;p=p.nextEntry) {if(count+1==index){Entry<E> newEntry=new Entry<E>(e,p.nextEntry);p.nextEntry=newEntry;size++;modCount++;return;}count++;}}
Java代碼 先進行判斷index是否正確,規(guī)定不能插入null鏈表。而且不能跳著走,畢竟鏈表要連起來。由于要找到前一個,但是表頭的前一個是沒有的,所以index==0時要單獨判斷。后面則用count進行計數(shù),找到其index-1節(jié)點,然后進行插隊處理。(4)、尾插入。其實也是插隊了,只是總是需要插到最后一個之后。Java代碼
public void add(E e){ if(head==null){ this.addFirst(e); }else{ this.addSpecifyIndex(e, size); } } public void add(E e){if(head==null){this.addFirst(e);}else{this.addSpecifyIndex(e, size);}} (5)、指定節(jié)點獲取元素。效率低,同樣從頭開始找到指定的節(jié)點把其中元素取出Java代碼
public E get(int index){ if(index<0||index>=size){ throw new NoSuchElementException(); } E result=null; int count=0; for (Entry<E> p=head;p!=null;p=p.nextEntry) { if(count==index){ result=p.e; } count++; } return result; } public E get(int index){if(index<0||index>=size){throw new NoSuchElementException();}E result=null;int count=0;for (Entry<E> p=head;p!=null;p=p.nextEntry) {if(count==index){result=p.e;}count++;}return result;}
Java代碼 (6)、指定節(jié)點刪除。效率低,同樣需要找到指定節(jié)點前一節(jié)點,直接把指定節(jié)點跳過就好了。Java代碼
public void remove(int index){ if(index<0||index>=size){ throw new NoSuchElementException(); } if(index==0){ head=head.nextEntry; size--; modCount++; return; } int count=0; for (Entry<E> p=head;p.nextEntry!=null;p=p.nextEntry) { if(count+1==index){ p.nextEntry=p.nextEntry.nextEntry; size--; modCount++; break; } count++; } } public void remove(int index){if(index<0||index>=size){throw new NoSuchElementException();}if(index==0){head=head.nextEntry;size--;modCount++;return;}int count=0;for (Entry<E> p=head;p.nextEntry!=null;p=p.nextEntry) {if(count+1==index){p.nextEntry=p.nextEntry.nextEntry;size--;modCount++;break;}count++;}} (7)、循環(huán)。為了好進行遍歷演示,下面的就是循環(huán)遍歷所用的了,大家隨意看一下就好了。Java代碼
private transient Entry<E> current; public void setCursor(int index){ if(index<0||index>=size){ throw new NoSuchElementException(); } int count=0; for (Entry<E> p=head;p!=null;p=p.nextEntry) { if(count==index){ current=p; break; } count++; } } public boolean hasNext(){ return current!=null; } public E next(){ E result=current.e; current=current.nextEntry; return result; } private transient Entry<E> current;public void setCursor(int index){if(index<0||index>=size){throw new NoSuchElementException();}int count=0;for (Entry<E> p=head;p!=null;p=p.nextEntry) {if(count==index){current=p;break;}count++;}}public boolean hasNext(){return current!=null;}public E next(){E result=current.e;current=current.nextEntry;return result;} 三、測試。。一個main方法,測試一下。Java代碼
public static void main(String[] args) { SingleChain<String> singleChain=new SingleChain<String>(); for (int i = 0; i < 4; i++) { singleChain.add(i+""); } //頭插入
// singleChain.addHead("head"); //尾插入
// singleChain.add("tail"); //指定節(jié)點插入
// singleChain.addSpecifyIndex("Specify", 1); //指定節(jié)點刪除
// singleChain.remove(3); //設(shè)置循環(huán)的初始節(jié)點 singleChain.setCursor(0); int count=0; System.out.println("######SIZE"+singleChain.size()+"#######"); while(singleChain.hasNext()){ System.out.println("index:"+count+",entry:"+singleChain.next()); count++; } System.out.println(singleChain.get(singleChain.size()-1)); } public static void main(String[] args) {SingleChain<String> singleChain=new SingleChain<String>();for (int i = 0; i < 4; i++) {singleChain.add(i+"");}//頭插入
// singleChain.addHead("head");//尾插入
// singleChain.add("tail");//指定節(jié)點插入
// singleChain.addSpecifyIndex("Specify", 1);//指定節(jié)點刪除
// singleChain.remove(3);//設(shè)置循環(huán)的初始節(jié)點singleChain.setCursor(0);int count=0;System.out.println("######SIZE"+singleChain.size()+"#######");while(singleChain.hasNext()){System.out.println("index:"+count+",entry:"+singleChain.next());count++;}System.out.println(singleChain.get(singleChain.size()-1));} 四、全部代碼Java代碼
package paladin.chain; import java.util.NoSuchElementException; public class SingleChain<E> implements Chain<E>{ private Entry<E> head; private transient Entry<E> current; private int size; private int modCount; private void addFirst(E e){ head=new Entry<E>(e,null); size++; modCount++; } public void addHead(E e){ if(head==null){ this.addFirst(e); }else{ Entry<E> newEntry=new Entry<E>(e,head); head=newEntry; size++; modCount++; } } public void addSpecifyIndex(E e,int index){ if(index<0||index>size||size==0){ throw new NoSuchElementException(); } if(index==0){ this.addHead(e); return; } int count=0; for (Entry<E> p=head; p!=null;p=p.nextEntry) { if(count+1==index){ Entry<E> newEntry=new Entry<E>(e,p.nextEntry); p.nextEntry=newEntry; size++; modCount++; return; } count++; } } public void add(E e){ if(head==null){ this.addFirst(e); }else{ this.addSpecifyIndex(e, size); } } public E get(int index){ if(index<0||index>=size){ throw new NoSuchElementException(); } E result=null; int count=0; for (Entry<E> p=head;p!=null;p=p.nextEntry) { if(count==index){ result=p.e; } count++; } return result; } public void remove(int index){ if(index<0||index>=size){ throw new NoSuchElementException(); } if(index==0){ head=head.nextEntry; size--; modCount++; return; } int count=0; for (Entry<E> p=head;p.nextEntry!=null;p=p.nextEntry) { if(count+1==index){ p.nextEntry=p.nextEntry.nextEntry; size--; modCount++; break; } count++; } } public void setCursor(int index){ if(index<0||index>=size){ throw new NoSuchElementException(); } int count=0; for (Entry<E> p=head;p!=null;p=p.nextEntry) { if(count==index){ current=p; break; } count++; } } public boolean hasNext(){ return current!=null; } public E next(){ E result=current.e; current=current.nextEntry; return result; } public int size(){ return this.size; } public static void main(String[] args) { SingleChain<String> singleChain=new SingleChain<String>(); for (int i = 0; i < 4; i++) { singleChain.add(i+""); } //頭插入
// singleChain.addHead("head"); //尾插入
// singleChain.add("tail"); //指定節(jié)點插入
// singleChain.addSpecifyIndex("Specify", 1); //指定節(jié)點刪除
// singleChain.remove(3); //設(shè)置循環(huán)的初始節(jié)點 singleChain.setCursor(0); int count=0; System.out.println("######SIZE"+singleChain.size()+"#######"); while(singleChain.hasNext()){ System.out.println("index:"+count+",entry:"+singleChain.next()); count++; } System.out.println(singleChain.get(singleChain.size()-1)); } private static class Entry<E>{ E e; Entry<E> nextEntry; public Entry(E e,Entry<E> nextEntry){ this.e=e; this.nextEntry=nextEntry; } }
}
總結(jié)
以上是生活随笔為你收集整理的java实现单向链表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java内部类作用全解
- 下一篇: Java实现双向链表