一、自定义迭代器。链表用来存储数据,就必须有访问的数据的工具。代码如下:
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 在插入时,要进行循环遍历。
欢迎大家指点。