一、自定义迭代器。链表用来存储数据,就必须有访问的数据的工具。代码如下:
import java.util.Iterator; public interface SingleListIterator<E> extends Iterator<E> { boolean hasNext(); E next(); void remove(); void set(E e); void add(E e); }
二、链表实现如下:
import java.util.List; public class SingleLinkedList<E> extends AbstractSingleLinkedList<E> implements List<E> ,java.io.Serializable { private static final long serialVersionUID = -3146637576067909980L; private transient Entry<E> header = null; private transient int size ; // 指向最未端 private transient Entry<E> lastElement = null; @Override public SingleListIterator<E> singleListIterator() { return new SingleIterator(); } public SingleLinkedList() { header = new Entry<E>(null, null); lastElement = header; size ++; } public E getLast() { return lastElement.element; } @Override public boolean remove(Object o) { boolean result = false; if (o == null) { for (Entry<E> beforElement = header; beforElement != null; beforElement = beforElement.next) { Entry<E> e = beforElement.next; if (e != null && e.element == null) { beforElement.next = e.next; result = true; if (e.equals(lastElement)) { lastElement = beforElement; } size --; } } } else { for (Entry<E> beforElement = header; beforElement != null; beforElement = beforElement.next) { Entry<E> e = beforElement.next; if (e != null && o.equals(e.element)) { beforElement.next = e.next; result = true; if (e.equals(lastElement)) { lastElement = beforElement; } size --; } } } return result; } @Override public E remove(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); } Entry<E> e = header; Entry<E> before = header; for (int i = 0; i < index; i++) { before = before.next; } e = before.next; before.next = e.next; if (index == size() -1) { lastElement = before; } size --; return e.element; } @Override public void add(int index,E element) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); } Entry<E> e = header; Entry<E> before = header; for (int i = 0; i < index; i++) { before = before.next; } e = before.next; before.next = new Entry<E>(element, e); size ++; } @Override public boolean add(E e) { lastElement.next = new Entry<E>(e, null); lastElement = lastElement.next; size ++; return true; } @Override public E get(int index) { return entry(index).element; } private Entry<E> entry(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); } Entry<E> e = header; for (int i = 0; i <= index; i++) { e = e.next; } return e; } @Override public int size() { return size - 1; } private static class Entry<E> { E element; Entry<E> next; public Entry(E element, Entry<E> next) { this.element = element; this.next = next; } } private class SingleIterator implements SingleListIterator<E> { // 最后访问的结点 private Entry<E> lastReturned = header.next; // 中间访问的结点 private Entry<E> beforeElement = header; // 最前访问的结点 private Entry<E> previousElement = beforeElement; @Override public boolean hasNext() { // 非循环单链表最后是null return lastReturned != null; } @Override public E next() { previousElement = beforeElement; beforeElement = lastReturned; E e = lastReturned.element; lastReturned = lastReturned.next; return e; } @Override public void remove() { previousElement.next = lastReturned; // 删除的是中间的结点,删除完后,中间的结点指向最前结点 beforeElement = previousElement; size --; } @Override public void set(E e) { beforeElement.element = e; } @Override public void add(E e) { // 若前后结点与中单结点相等,是在执行删除后,接着执行add操作 if (previousElement == beforeElement) { previousElement.next = beforeElement = new Entry<E>(e, lastReturned); } else { previousElement.next = new Entry<E>(e, beforeElement); } size ++; } } }
三、 测试数据如下:
import java.util.ArrayList; import java.util.List; public class SingleLinkedListTest { public static void main(String[] args) { SingleLinkedList<Integer> arr = new SingleLinkedList<Integer>(); arr.add(456); arr.add(789); arr.add(0,123); arr.add(789); arr.add(741); //arr.remove(3); arr.add(963); SingleListIterator<Integer> it = arr.singleListIterator(); System.out.println(arr.size()); List<Integer> remove = new ArrayList<Integer>(); remove.add(789); while (it.hasNext()) { Integer val = it.next(); if (remove.contains(val)) { it.remove(); } } for (Integer integer : arr) { System.out.println(integer); } System.out.println(arr.size()); } }
四、优点:最初的想法是用来锻炼自己的算法设计能力。写完后,发现SingleLinkedList 比 LinkedList 在插入数据的效率略高,理由是:SingleLinkedList 有一个lastElement 变量,指高链表的最后,而 LinkedList 在插入时,要进行循环遍历。
欢迎大家指点。