java实现单向链表

来源:互联网 发布:json数组保存到数据库 编辑:程序博客网 时间:2024/05/22 02:51
一、单向链表的结构。     (1)、首先节点的结构,其中包含本节点内容,以及需要指向下一个节点。 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则指向本节点的对象,而nextEntry则指向下一个节点。      (2)、任何时候都需要知道表头在哪里。毕竟是单向链表嘛,因为只有一个方向,找到了表头就能找到全部。        Java代码  private  Entry<E> head;  private  Entry<E> head;      (3)、还可以记录链表中总共有多少个节点。它是在某些判断时为了提高效率而存在的。不是绝对需要的。毕竟知道表头后,一个一个按顺序去寻找就好了。Java代码  private  int size;     public int size(){           return this.size;       }  private  int size;public int size(){return this.size;}Java代码        好了有这三样,就足够了。就看我们如何用他们了。 二、内部实现。    (1)、第一次向链表中插入。此时链表中节点为null,第一次插入,无非就是把节点头插入而已。 可以看出就是把链表头初始化了,并且链表大小涨1。其中modCount记录整个链表修改的次数,链表的增加和删除它都会增加。毕竟第一次插入相对外调用是透明的,所以应该是私有的咯。(透明就是不可见,这里只得是外部没必要知道它的存在)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的时候,则表明链表中没值,只需调用第一次插入。否则对给定的元素创新增一个节点,新增节点的下一个指向头节点,当然此时自己已经变成头结点了,索引要更新头节点的引用。(可以看出想要清空链表,只需要将头置为null就好了)    (3)、指定节点插入(插队)。在链表的指定节点插入一个元素,效率非常低。由于规则上你只能从队伍第一个开始往后找,找到你要插队位置的前一个,并将你插入其中,你先要告诉你身前人你在他身后,并且你自己要清楚你身后是谁。反正够麻烦的。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是否正确,规定不能插入null链表。而且不能跳着走,毕竟链表要连起来。由于要找到前一个,但是表头的前一个是没有的,所以index==0时要单独判断。后面则用count进行计数,找到其index-1节点,然后进行插队处理。     (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)、指定节点获取元素。效率低,同样从头开始找到指定的节点把其中元素取出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)、指定节点删除。效率低,同样需要找到指定节点前一节点,直接把指定节点跳过就好了。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)、循环。为了好进行遍历演示,下面的就是循环遍历所用的了,大家随意看一下就好了。 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");           //指定节点插入   //      singleChain.addSpecifyIndex("Specify", 1);           //指定节点删除   //      singleChain.remove(3);           //设置循环的初始节点           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");//指定节点插入//singleChain.addSpecifyIndex("Specify", 1);//指定节点删除//singleChain.remove(3);//设置循环的初始节点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");           //指定节点插入   //      singleChain.addSpecifyIndex("Specify", 1);           //指定节点删除   //      singleChain.remove(3);           //设置循环的初始节点           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;           }       }   }  

原创粉丝点击