A, ListaEnlazada visión general
- Lista enlazada es una lista doblemente enlazada para lograr Lista
- LinkedList no seguro para subprocesos
- Elemento permite LinkedList es nulo, lo que permite elemento de repetición
- LinkedList se lleva a cabo sobre la base de la lista, por lo que elimina la inserción de alta eficiencia, baja eficiencia de búsqueda (aunque hay una acción acelerada)
- LinkedList se basa en la realización de la lista, por lo que no hay ningún problema de capacidad insuficiente, lo que no hay método de expansión
- LinkedList también logró pila de espera y el método de operación, y por lo tanto puede ser utilizado como una pila, y las colas utiliza deque
Dos, análisis LinkedList
estructura de almacenamiento LinkedList
LinkedList es una estructura de datos de lista doblemente enlazada que consiste en
public class LinkedList{
// 元素个数
transient int size = 0;
/**
指向第一个节点的指针
不变性:
1. 如果first = null,则last=null
2. 如果first.prev == null,则first.item != null
*/
transient Node<E> first;
/**
指向最后一个节点的指针
不变性:
1. 如果first = null,则last = null
2. 如果last.next == null,则last.item != null
*/
transient Node<E> last;
private static class Node<E> { E item;
Node<E> next; // 下一个Node的引用
Node<E> prev; // 上一个Node的引用
Node(Node<E> prev, E element, Node<E> next) { this.item = element;
this.next = next; this.prev = prev;
}
}
/**
创建一个空list
* */
public LinkedList() {
}
public LinkedList(Collection<? extends E> c) { this();
addAll(c);
}
}
Adición de elementos
Añadir a la cabeza
// 从头插入
public void addFirst(E e) {
linkFirst(e);
}
private void linkFirst(E e) { final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f); first = newNode;
if (f == null) // 当前List中没有元素,size=0
last = newNode; else
f.prev = newNode; size++;
modCount++;
}
para anexar
public boolean add(E e) { linkLast(e);
return true;
}
public void addLast(E e) { linkLast(e);
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null); last = newNode;
if (l == null)// 当前List中没有元素,size=0
first = newNode; else
l.next = newNode; size++;
modCount++;
}
nodo de eliminación
Borrar de la cabeza
// 移除首节点,并返回该节点的元素值
public E remove() { return removeFirst();
}
public E removeFirst() { final Node<E> f = first; if (f == null)
throw new NoSuchElementException(); return unlinkFirst(f);
}
// 删除首节点f
private E unlinkFirst(Node<E> f) { final E element = f.item; final Node<E> next = f.next; f.item = null;
f.next = null; // help GC first = next;
if (next == null) // size=1 last = null;
else
next.prev = null; size--;
modCount++; return element;
}
Eliminado de la cola
public E removeLast() { final Node<E> l = last; if (l == null)
throw new NoSuchElementException(); return unlinkLast(l);
}
private E unlinkLast(Node<E> l) { final E element = l.item; final Node<E> prev = l.prev; l.item = null;
l.prev = null; // help GC last = prev;
if (prev == null) // size=1 first = null;
else
prev.next = null; size--;
modCount++; return element;
}
Fuera del índice
public E remove(int index) { checkElementIndex(index);// 检查索引index范围return unlink(node(index));
}
E unlink(Node<E> x) {
final E element = x.item; final Node<E> next = x.next; final Node<E> prev = x.prev;
if (prev == null) {// x为首节点first = next;
} else {
prev.next = next; x.prev = null;
}
if (next == null) {// x为尾节点last = prev;
} else {
next.prev = prev; x.next = null;
}
x.item = null; size--; modCount++; return element;
}
La obtención de datos de nodo
Obtener datos de cabecera
// 获取首节点的数据
public E getFirst() {
final Node<E> f = first; if (f == null)
throw new NoSuchElementException(); return f.item;
}
la cola de adquisición de datos
// 获取尾节点的数据
public E getLast() {
final Node<E> l = last; if (l == null)
throw new NoSuchElementException(); return l.item;
}
La obtención de los datos del nodo índice
// 获取索引对应节点的数据
public E get(int index) { checkElementIndex(index); return node(index).item;
}
// 类似折半查找
Node<E> node(int index) {
if (index < (size >> 1)) {// 从前半部分查找
Node<E> x = first;
for (int i = 0; i < index; i++) x = x.next;
return x;
} else {// 从后半部分查找
Node<E> x = last;
for (int i = size - 1; i > index; i--) x = x.prev;
return x;
}
}
En tercer lugar, el resumen: Comparar la ArrayList y LinkedList
ArrayList velocidad de inserción de secuencia será más rápido, porque array ArrayList se implementa sobre la base de, las nuevas matrices son bien por adelantado, siempre que el enchufe a una datos de posición especificados como
LinkedList es diferente, cada orden de inserción cuando un nuevo objetos ListaEnlazada se salen, si el objeto es relativamente grande, entonces el nuevo presidente un poco de tiempo atado, además de algunos asignación de referencia de funcionamiento, el orden de inserción necesariamente más lento que ArrayList LinkedList
Atravesando la eficiencia ArrayList será más alta que la eficiencia de atravesar algunos de LinkedList
LinkedList no insertar, eliminar, cuando lenta para hacer frente a la rápida sólo tenga que cambiar antes y después de la dirección de nodo de referencia
ArrayList no insertar, eliminar, cuando en los elementos de copia masiva de matriz lentos en el direccionamiento rápido
Si se trata de inserción determinado, los elementos de eliminación en la primera mitad, a continuación, utilizar ListaEnlazada
Si se trata de inserción determinado, los elementos de borrado en la posición en comparación, considerar el uso de ArrayList
Si no está seguro de inserción, borrar ¿Dónde está? Recomendado LinkedList,
Como un inserto ListaEnlazada conjunto, la eficiencia de eliminación es relativamente estable, no hay más vuelta antes ArrayList este caso
En segundo inserto elementos cuando el desastre que se llevará a cabo una vez que la expansión ArrayList, y la expansión del subyacente ArrayList matriz es a la vez tiempo y operación que consume espacio-