实现了一个简单难度doubly linked list
- LinkedList的优点:假定位置是已知的,新项的插入和现有项的删除均开销很小
- LinkedList的缺点:不容易作索引,对get的调用是很昂贵的
- 要访问特定元素,只能从链表头开始,遍历到该元素,时间复杂度为 O(n)。
- 在特定的数据元素之后(前)插入或删除元素,不涉及到其他元素的移动,因此时间复杂度为 O(1)。
MyLinkedList.java
package doppler.List;
public class MyLinkedList<AnyType> implements Iterable<AnyType> {
private int theSize;
private int modCount = 0;
private Node<AnyType> beginMarker;
private Node<AnyType> endMarker;
private static class Node<AnyType> {
public Node(AnyType d, Node<AnyType> p, Node<AnyType> n) {
data = d;
prev = p;
next = n;
}
public AnyType data;
public Node<AnyType> prev;
public Node<AnyType> next;
}
public MyLinkedList() {
clear();
}
public void clear() {
beginMarker = new Node<AnyType>(null, null, null);
endMarker = new Node<AnyType>(null, beginMarker, null);
beginMarker.next = endMarker;
theSize = 0;
modCount++;
}
public int Size() {
return theSize;
}
public boolean isEmpty() {
return Size() == 0;
}
public boolean add(AnyType x) {
add(Size(), x);
return true;
}
public void add(int index, AnyType x) {
addBefore(getNode(index), x);
}
public AnyType get(int index){
return getNode(index).data;
}
public AnyType set(int index, AnyType newValue ){
Node<AnyType> p=getNode(index);
AnyType oldValue=p.data;
p.data=newValue;
return oldValue;
}
public AnyType remove(int index){
return remove(getNode(index));
}
private void addBefore(Node<AnyType> p, AnyType x) {
p.prev = p.prev.next = new Node<AnyType>(x, p.prev, p);
theSize++;
modCount++;
}
private AnyType remove(Node<AnyType> p) {
p.prev.next = p.next;
p.next.prev = p.prev;
theSize--;
modCount++;
return p.data;
}
private Node<AnyType> getNode(int index){
Node<AnyType> p;
if (index < 0 || index > Size()) {
throw new IndexOutOfBoundsException();
}
if (index < Size()/2 ) {
p=beginMarker;
for(int i = 0;i < index; i++){
p=p.next;
}
}
else {
p=endMarker;
for(int i = Size();i > index;i--){
p=p.prev;
}
}
return p;
}
public java.util.Iterator<AnyType> iterator(){
return new LinkedListIterator();
}
private class LinkedListIterator implements java.util.Iterator<AnyType>{
private Node<AnyType> current = beginMarker;
private int expectedModConut = modCount;
private boolean okToRemove = false;
public boolean hasNext(){
return current != endMarker;
}
public AnyType next(){
if (modCount != expectedModConut) {
throw new java.util.ConcurrentModificationException();
}
if (!hasNext()) {
throw new java.util.NoSuchElementException();
}
AnyType nextItem = current.data;
current=current.next;
okToRemove=true;
return nextItem;
}
public void remove(){
if (modCount != expectedModConut) {
throw new java.util.ConcurrentModificationException();
}
if (!okToRemove) {
throw new IllegalStateException();
}
MyLinkedList.this.remove(current.prev);
okToRemove = false;
expectedModConut++;
}
}
}
MyLinkedListDemo.java
package doppler.test
import doppler.List.MyLinkedList
public class MyLinkedListDemo {
public static void main(String[] args) {
MyLinkedList<Integer> myLinkedList=new MyLinkedList<>()
myLinkedList.add(5)
myLinkedList.add(4)
myLinkedList.add(3)
myLinkedList.add(2)
myLinkedList.add(1)
for (Integer integer : myLinkedList) {
System.out.print(integer+" ")
}
System.out.println()
myLinkedList.add(9)
for (Integer integer : myLinkedList) {
System.out.print(integer+" ")
}
System.out.println()
myLinkedList.add(3, 6)
for (Integer integer : myLinkedList) {
System.out.print(integer+" ")
}
System.out.println()
myLinkedList.set(0, 6)
for (Integer integer : myLinkedList) {
System.out.print(integer+" ")
}
System.out.println()
myLinkedList.remove(myLinkedList.Size()-1)
for (Integer integer : myLinkedList) {
System.out.print(integer+" ")
}
System.out.println()
System.out.print(myLinkedList.get(myLinkedList.Size()-1))
}
}