参考书目《数据结构与算法分析java语言描述—第二版》
要注意头结点和尾节点不包括在链表长度之内!
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class MyLinkedList {
private int theSize;
private int modCount = 0;
//表示自从构造以来对链表所做改变的次数,指增加或删除节点的次数
private Node<Integer> beginMarker;
private Node<Integer> endMarker;
public static void main(String[] args) {
MyLinkedList myl = new MyLinkedList();
myl.add(1);
myl.add(2);
myl.add(3);
myl.add(4);
myl.add(5);
myl.add(6);
//1,2,3,4,5,6
System.out.println(myl.size());
//打印链表长度6
//返回链表指定位置上的数据4
System.out.println(myl.set(3, 10));
//将链表指定位置上的数据修改,并返回原数据
//1,2,3,10,5,6
myl.remove(3);//删除idx=3位置上的节点,即1,2,3,5,6
Iterator<Integer> it = myl.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
//构造函数
public MyLinkedList(){
clear();//将链表清空
}
//建立新节点
private static class Node<Integer>{
public Integer data;
public Node<Integer> prev;
public Node<Integer> next;
public Node(Integer d,Node<Integer> p,Node<Integer> n){
data = d;
prev = p;
next = n;
}
}
//清空链表
public void clear() {
beginMarker = new Node<Integer>(null,null,null);
endMarker = new Node<Integer>(null,beginMarker,null);
beginMarker.next = endMarker;
theSize = 0;
modCount++;
}
//返回链表的长度
public int size(){
return theSize;
}
//判断链表是否为空
public boolean isEmpty(){
return size()==0;
}
//在链表结尾添加新的节点
public boolean add(Integer x){
add(size(),x);
return true;
}
//在链表指定位置idx添加新的节点,x是节点的数据值data
public void add(int idx, Integer x) {
addBefore(getNode(idx),x);
//本例中相当于在尾节点之前添加新节点
}
//返回链表指定位置的数据
public Integer get(int idx){
return getNode(idx).data;
}
//修改链表指定位置的数据
//并返回原数据
public Integer set(int idx,Integer newVal){
Node<Integer> p = getNode(idx);
Integer oldVal = p.data;
p.data = newVal;
return oldVal;
}
//删除链表指定位置的节点
public Integer remove(int idx){
return remove(getNode(idx));
}
//在某个节点之前添加新节点
private void addBefore(Node<Integer> p,Integer x){
Node<Integer> newNode = new Node<Integer>(x,p.prev,p);
newNode.prev.next = newNode;
p.prev = newNode;
theSize++;
modCount++;
}
//删除某个节点
private Integer remove(Node<Integer> p){
p.next.prev = p.prev;
p.prev.next = p.next;
theSize--;
modCount++;
return p.data;
}
//返回指定位置idx上的节点
//注意:size()返回的值不包括头节点和尾节点
private Node<Integer> getNode(int idx){
Node<Integer> p;
if(idx<0||idx>size()){
throw new IndexOutOfBoundsException();
}
//折半查找,可以提高查找效率
if(idx<size()/2){
p = beginMarker.next;
for(int i = 0;i<idx;i++){
p = p.next;
}
}else{
p = endMarker;
for(int i = size();i>idx;i--){
p = p.prev;
}
}
return p;
}
public Iterator<Integer> iterator(){
return new LinkedListIterator();
}
private class LinkedListIterator implements Iterator<Integer>{
private Node<Integer> current = beginMarker.next;
private int exceptedModCount = modCount;
private boolean okToRemove = false;
public boolean hasNext(){
return current != endMarker;
//如果current不指向尾节点则继续向后遍历
}
public Integer next(){
if(modCount!=exceptedModCount){
//当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
throw new ConcurrentModificationException();
}
if(!hasNext()){
throw new NoSuchElementException();
}
Integer nextItem = current.data;
current = current.next;
okToRemove = true;
return nextItem;//返回遍历到的数据
}
public void remove(){
if(modCount!=exceptedModCount){
throw new ConcurrentModificationException();
}
if(!okToRemove){
//在非法或不适当的时间调用方法时产生的信号。
//换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。
throw new IllegalStateException();
}
MyLinkedList.this.remove(current.prev);
okToRemove = false;
exceptedModCount++;
}
}
}