- [ç®ä»](#ç®ä»)
- [å
é¨ç»æåæ](#å
é¨ç»æåæ)
- [LinkedListæºç åæ](#linkedlistæºç åæ)
- [æé æ¹æ³](#æé æ¹æ³)
- [æ·»å ï¼addï¼æ¹æ³](#addæ¹æ³)
- [æ ¹æ®ä½ç½®åæ°æ®çæ¹æ³](#æ ¹æ®ä½ç½®åæ°æ®çæ¹æ³)
- [æ ¹æ®å¯¹è±¡å¾å°ç´¢å¼çæ¹æ³](#æ ¹æ®å¯¹è±¡å¾å°ç´¢å¼çæ¹æ³)
- [æ£æ¥é¾è¡¨æ¯å¦å
å«æå¯¹è±¡çæ¹æ³ï¼](#æ£æ¥é¾è¡¨æ¯å¦å
å«æå¯¹è±¡çæ¹æ³ï¼)
- [å é¤ï¼remove/popï¼æ¹æ³](#å 餿¹æ³)
- [LinkedListç±»å¸¸ç¨æ¹æ³æµè¯ï¼](#linkedlistç±»å¸¸ç¨æ¹æ³æµè¯)
## ç®ä»
LinkedListæ¯ä¸ä¸ªå®ç°äºListæ¥å£åDequeæ¥å£çå端é¾è¡¨ã
LinkedListåºå±çé¾è¡¨ç»æä½¿å®æ¯æé«æçæå
¥åå 餿ä½ï¼å¦å¤å®å®ç°äºDequeæ¥å£ï¼ä½¿å¾LinkedListç±»ä¹å
·æéåçç¹æ§;
LinkedList䏿¯çº¿ç¨å®å
¨çï¼å¦ææ³ä½¿LinkedListåæçº¿ç¨å®å
¨çï¼å¯ä»¥è°ç¨éæç±»Collectionsç±»ä¸çsynchronizedListæ¹æ³ï¼
```java
List list=Collections.synchronizedList(new LinkedList(...));
```
## å
é¨ç»æåæ
**å¦ä¸å¾æç¤ºï¼**

çå®äºå¾ä¹åï¼æä»¬åçLinkedListç±»ä¸çä¸ä¸ª**å
é¨ç§æç±»Node**å°±å¾å¥½çè§£äºï¼
```java
private static class Node {
E item;//èç¹å¼
Node next;//åç»§èç¹
Node prev;//å驱èç¹
Node(Node prev, E element, Node next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
```
è¿ä¸ªç±»å°±ä»£è¡¨å端é¾è¡¨çèç¹Nodeãè¿ä¸ªç±»æä¸ä¸ªå±æ§ï¼å嫿¯å驱èç¹ï¼æ¬èç¹çå¼ï¼åç»§ç»ç¹ã
## LinkedListæºç åæ
### æé æ¹æ³
**空æé æ¹æ³ï¼**
```java
public LinkedList() {
}
```
**ç¨å·²æçéåå建é¾è¡¨çæé æ¹æ³ï¼**
```java
public LinkedList(Collection extends E> c) {
this();
addAll(c);
}
```
### addæ¹æ³
**add(E e)** æ¹æ³ï¼å°å
ç´ æ·»å å°é¾è¡¨å°¾é¨
```java
public boolean add(E e) {
linkLast(e);//è¿éå°±åªè°ç¨äºè¿ä¸ä¸ªæ¹æ³
return true;
}
```
```java
/**
* 龿¥ä½¿eä½ä¸ºæåä¸ä¸ªå
ç´ ã
*/
void linkLast(E e) {
final Node l = last;
final Node newNode = new Node<>(l, e, null);
last = newNode;//æ°å»ºèç¹
if (l == null)
first = newNode;
else
l.next = newNode;//æååç»§å
ç´ ä¹å°±æ¯æåä¸ä¸ä¸ªå
ç´
size++;
modCount++;
}
```
**add(int index,E e)**ï¼å¨æå®ä½ç½®æ·»å å
ç´
```java
public void add(int index, E element) {
checkPositionIndex(index); //æ£æ¥ç´¢å¼æ¯å¦å¤äº[0-size]ä¹é´
if (index == size)//æ·»å å¨é¾è¡¨å°¾é¨
linkLast(element);
else//æ·»å å¨é¾è¡¨ä¸é´
linkBefore(element, node(index));
}
```
linkBeforeæ¹æ³éè¦ç»å®ä¸¤ä¸ªåæ°ï¼ä¸ä¸ªæå
¥èç¹çå¼ï¼ä¸ä¸ªæå®çnodeï¼æä»¥æä»¬åè°ç¨äºNode(index)廿¾å°index对åºçnode
**addAll(Collection c )ï¼å°éåæå
¥å°é¾è¡¨å°¾é¨**
```java
public boolean addAll(Collection extends E> c) {
return addAll(size, c);
}
```
**addAll(int index, Collection c)ï¼** å°éå仿å®ä½ç½®å¼å§æå
¥
```java
public boolean addAll(int index, Collection extends E> c) {
//1:æ£æ¥indexèå´æ¯å¦å¨sizeä¹å
checkPositionIndex(index);
//2:toArray()æ¹æ³æéåçæ°æ®åå°å¯¹è±¡æ°ç»ä¸
Object[] a = c.toArray();
int numNew = a.length;
if (numNew == 0)
return false;
//3ï¼å¾å°æå
¥ä½ç½®çå驱èç¹ååç»§èç¹
Node pred, succ;
//妿æå
¥ä½ç½®ä¸ºå°¾é¨ï¼å驱èç¹ä¸ºlastï¼åç»§èç¹ä¸ºnull
if (index == size) {
succ = null;
pred = last;
}
//å¦åï¼è°ç¨node()æ¹æ³å¾å°åç»§èç¹ï¼åå¾å°å驱èç¹
else {
succ = node(index);
pred = succ.prev;
}
// 4ï¼éåæ°æ®å°æ°æ®æå
¥
for (Object o : a) {
@SuppressWarnings("unchecked") E e = (E) o;
//å建æ°èç¹
Node newNode = new Node<>(pred, e, null);
//妿æå
¥ä½ç½®å¨é¾è¡¨å¤´é¨
if (pred == null)
first = newNode;
else
pred.next = newNode;
pred = newNode;
}
//妿æå
¥ä½ç½®å¨å°¾é¨ï¼éç½®lastèç¹
if (succ == null) {
last = pred;
}
//å¦åï¼å°æå
¥çé¾è¡¨ä¸å
åé¾è¡¨è¿æ¥èµ·æ¥
else {
pred.next = succ;
succ.prev = pred;
}
size += numNew;
modCount++;
return true;
}
```
ä¸é¢å¯ä»¥çåºaddAllæ¹æ³é常å
æ¬ä¸é¢å个æ¥éª¤ï¼
1. æ£æ¥indexèå´æ¯å¦å¨sizeä¹å
2. toArray()æ¹æ³æéåçæ°æ®åå°å¯¹è±¡æ°ç»ä¸
3. å¾å°æå
¥ä½ç½®çå驱ååç»§èç¹
4. éåæ°æ®ï¼å°æ°æ®æå
¥å°æå®ä½ç½®
**addFirst(E e)ï¼** å°å
ç´ æ·»å å°é¾è¡¨å¤´é¨
```java
public void addFirst(E e) {
linkFirst(e);
}
```
```java
private void linkFirst(E e) {
final Node f = first;
final Node newNode = new Node<>(null, e, f);//æ°å»ºèç¹ï¼ä»¥å¤´èç¹ä¸ºåç»§èç¹
first = newNode;
//妿é¾è¡¨ä¸ºç©ºï¼lastèç¹ä¹æå该èç¹
if (f == null)
last = newNode;
//å¦åï¼å°å¤´èç¹çå驱æéæåæ°èç¹ï¼ä¹å°±æ¯æååä¸ä¸ªå
ç´
else
f.prev = newNode;
size++;
modCount++;
}
```
**addLast(E e)ï¼** å°å
ç´ æ·»å å°é¾è¡¨å°¾é¨ï¼ä¸ **add(E e)** æ¹æ³ä¸æ ·
```java
public void addLast(E e) {
linkLast(e);
}
```
### æ ¹æ®ä½ç½®åæ°æ®çæ¹æ³
**get(int index)ï¼** æ ¹æ®æå®ç´¢å¼è¿åæ°æ®
```java
public E get(int index) {
//æ£æ¥indexèå´æ¯å¦å¨sizeä¹å
checkElementIndex(index);
//è°ç¨Node(index)廿¾å°index对åºçnodeç¶åè¿åå®çå¼
return node(index).item;
}
```
**è·å头èç¹ï¼index=0ï¼æ°æ®æ¹æ³:**
```java
public E getFirst() {
final Node f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
public E element() {
return getFirst();
}
public E peek() {
final Node f = first;
return (f == null) ? null : f.item;
}
public E peekFirst() {
final Node f = first;
return (f == null) ? null : f.item;
}
```
**åºå«ï¼**
getFirst(),element(),peek(),peekFirst()
è¿å个è·å头ç»ç¹æ¹æ³çåºå«å¨äºå¯¹é¾è¡¨ä¸ºç©ºæ¶çå¤çï¼æ¯æåºå¼å¸¸è¿æ¯è¿ånullï¼å
¶ä¸**getFirst()** å**element()** æ¹æ³å°ä¼å¨é¾è¡¨ä¸ºç©ºæ¶ï¼æåºå¼å¸¸
element()æ¹æ³çå
é¨å°±æ¯ä½¿ç¨getFirst()å®ç°çãå®ä»¬ä¼å¨é¾è¡¨ä¸ºç©ºæ¶ï¼æåºNoSuchElementException
**è·åå°¾èç¹ï¼index=-1ï¼æ°æ®æ¹æ³:**
```java
public E getLast() {
final Node l = last;
if (l == null)
throw new NoSuchElementException();
return l.item;
}
public E peekLast() {
final Node l = last;
return (l == null) ? null : l.item;
}
```
**两è
åºå«ï¼**
**getLast()** æ¹æ³å¨é¾è¡¨ä¸ºç©ºæ¶ï¼ä¼æåº**NoSuchElementException**ï¼è**peekLast()** åä¸ä¼ï¼åªæ¯ä¼è¿å **null**ã
### æ ¹æ®å¯¹è±¡å¾å°ç´¢å¼çæ¹æ³
**int indexOf(Object o)ï¼** ä»å¤´éåæ¾
```java
public int indexOf(Object o) {
int index = 0;
if (o == null) {
//ä»å¤´éå
for (Node x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
//ä»å¤´éå
for (Node x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
```
**int lastIndexOf(Object o)ï¼** ä»å°¾éåæ¾
```java
public int lastIndexOf(Object o) {
int index = size;
if (o == null) {
//ä»å°¾éå
for (Node x = last; x != null; x = x.prev) {
index--;
if (x.item == null)
return index;
}
} else {
//ä»å°¾éå
for (Node x = last; x != null; x = x.prev) {
index--;
if (o.equals(x.item))
return index;
}
}
return -1;
}
```
### æ£æ¥é¾è¡¨æ¯å¦å
å«æå¯¹è±¡çæ¹æ³ï¼
**contains(Object o)ï¼** æ£æ¥å¯¹è±¡oæ¯å¦åå¨äºé¾è¡¨ä¸
```java
public boolean contains(Object o) {
return indexOf(o) != -1;
}
```
### å 餿¹æ³
**remove()** ,**removeFirst(),pop():** å é¤å¤´èç¹
```
public E pop() {
return removeFirst();
}
public E remove() {
return removeFirst();
}
public E removeFirst() {
final Node f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
```
**removeLast(),pollLast():** å é¤å°¾èç¹
```java
public E removeLast() {
final Node l = last;
if (l == null)
throw new NoSuchElementException();
return unlinkLast(l);
}
public E pollLast() {
final Node l = last;
return (l == null) ? null : unlinkLast(l);
}
```
**åºå«ï¼** removeLast()å¨é¾è¡¨ä¸ºç©ºæ¶å°æåºNoSuchElementExceptionï¼èpollLast()æ¹æ³è¿ånullã
**remove(Object o):** å 餿å®å
ç´
```java
public boolean remove(Object o) {
//妿å é¤å¯¹è±¡ä¸ºnull
if (o == null) {
//ä»å¤´å¼å§éå
for (Node x = first; x != null; x = x.next) {
//æ¾å°å
ç´
if (x.item == null) {
//ä»é¾è¡¨ä¸ç§»é¤æ¾å°çå
ç´
unlink(x);
return true;
}
}
} else {
//ä»å¤´å¼å§éå
for (Node x = first; x != null; x = x.next) {
//æ¾å°å
ç´
if (o.equals(x.item)) {
//ä»é¾è¡¨ä¸ç§»é¤æ¾å°çå
ç´
unlink(x);
return true;
}
}
}
return false;
}
```
å½å 餿å®å¯¹è±¡æ¶ï¼åªéè°ç¨remove(Object o)å³å¯ï¼ä¸è¿è¯¥æ¹æ³ä¸æ¬¡åªä¼å é¤ä¸ä¸ªå¹é
ç对象ï¼å¦æå é¤äºå¹é
对象ï¼è¿åtrueï¼å¦åfalseã
unlink(Node x) æ¹æ³ï¼
```java
E unlink(Node x) {
// assert x != null;
final E element = x.item;
final Node next = x.next;//å¾å°åç»§èç¹
final Node prev = x.prev;//å¾å°å驱èç¹
//å é¤å驱æé
if (prev == null) {
first = next;//妿å é¤çèç¹æ¯å¤´èç¹,令头èç¹æå该èç¹çåç»§èç¹
} else {
prev.next = next;//å°å驱èç¹çåç»§èç¹æååç»§èç¹
x.prev = null;
}
//å é¤åç»§æé
if (next == null) {
last = prev;//妿å é¤çèç¹æ¯å°¾èç¹,令尾èç¹æå该èç¹çå驱èç¹
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
```
**remove(int index)**ï¼å 餿å®ä½ç½®çå
ç´
```java
public E remove(int index) {
//æ£æ¥indexèå´
checkElementIndex(index);
//å°èç¹å é¤
return unlink(node(index));
}
```
## LinkedListç±»å¸¸ç¨æ¹æ³æµè¯
```java
package list;
import java.util.Iterator;
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] srgs) {
//åå»ºåæ¾intç±»åçlinkedList
LinkedList linkedList = new LinkedList<>();
/************************** linkedListçåºæ¬æä½ ************************/
linkedList.addFirst(0); // æ·»å å
ç´ å°å表å¼å¤´
linkedList.add(1); // å¨å表ç»å°¾æ·»å å
ç´
linkedList.add(2, 2); // 卿å®ä½ç½®æ·»å å
ç´
linkedList.addLast(3); // æ·»å å
ç´ å°å表ç»å°¾
System.out.println("LinkedListï¼ç´æ¥è¾åºçï¼: " + linkedList);
System.out.println("getFirst()è·å¾ç¬¬ä¸ä¸ªå
ç´ : " + linkedList.getFirst()); // è¿åæ¤å表ç第ä¸ä¸ªå
ç´
System.out.println("getLast()è·å¾ç¬¬æåä¸ä¸ªå
ç´ : " + linkedList.getLast()); // è¿åæ¤å表çæåä¸ä¸ªå
ç´
System.out.println("removeFirst()å é¤ç¬¬ä¸ä¸ªå
ç´ å¹¶è¿å: " + linkedList.removeFirst()); // ç§»é¤å¹¶è¿åæ¤å表ç第ä¸ä¸ªå
ç´
System.out.println("removeLast()å 餿åä¸ä¸ªå
ç´ å¹¶è¿å: " + linkedList.removeLast()); // ç§»é¤å¹¶è¿åæ¤å表çæåä¸ä¸ªå
ç´
System.out.println("After remove:" + linkedList);
System.out.println("contains()æ¹æ³å¤æå表æ¯å¦å
å«1è¿ä¸ªå
ç´ :" + linkedList.contains(1)); // 夿æ¤å表å
嫿å®å
ç´ ï¼å¦ææ¯ï¼åè¿åtrue
System.out.println("该linkedListçå¤§å° : " + linkedList.size()); // è¿åæ¤å表çå
ç´ ä¸ªæ°
/************************** ä½ç½®è®¿é®æä½ ************************/
System.out.println("-----------------------------------------");
linkedList.set(1, 3); // å°æ¤åè¡¨ä¸æå®ä½ç½®çå
ç´ æ¿æ¢ä¸ºæå®çå
ç´
System.out.println("After set(1, 3):" + linkedList);
System.out.println("get(1)è·å¾æå®ä½ç½®ï¼è¿é为1ï¼çå
ç´ : " + linkedList.get(1)); // è¿åæ¤åè¡¨ä¸æå®ä½ç½®å¤çå
ç´
/************************** Searchæä½ ************************/
System.out.println("-----------------------------------------");
linkedList.add(3);
System.out.println("indexOf(3): " + linkedList.indexOf(3)); // è¿åæ¤å表ä¸é¦æ¬¡åºç°çæå®å
ç´ çç´¢å¼
System.out.println("lastIndexOf(3): " + linkedList.lastIndexOf(3));// è¿åæ¤åè¡¨ä¸æååºç°çæå®å
ç´ çç´¢å¼
/************************** Queueæä½ ************************/
System.out.println("-----------------------------------------");
System.out.println("peek(): " + linkedList.peek()); // è·åä½ä¸ç§»é¤æ¤å表ç头
System.out.println("element(): " + linkedList.element()); // è·åä½ä¸ç§»é¤æ¤å表ç头
linkedList.poll(); // è·åå¹¶ç§»é¤æ¤å表ç头
System.out.println("After poll():" + linkedList);
linkedList.remove();
System.out.println("After remove():" + linkedList); // è·åå¹¶ç§»é¤æ¤å表ç头
linkedList.offer(4);
System.out.println("After offer(4):" + linkedList); // å°æå®å
ç´ æ·»å å°æ¤åè¡¨çæ«å°¾
/************************** Dequeæä½ ************************/
System.out.println("-----------------------------------------");
linkedList.offerFirst(2); // 卿¤å表çå¼å¤´æå
¥æå®çå
ç´
System.out.println("After offerFirst(2):" + linkedList);
linkedList.offerLast(5); // 卿¤å表æ«å°¾æå
¥æå®çå
ç´
System.out.println("After offerLast(5):" + linkedList);
System.out.println("peekFirst(): " + linkedList.peekFirst()); // è·åä½ä¸ç§»é¤æ¤å表ç第ä¸ä¸ªå
ç´
System.out.println("peekLast(): " + linkedList.peekLast()); // è·åä½ä¸ç§»é¤æ¤å表ç第ä¸ä¸ªå
ç´
linkedList.pollFirst(); // è·åå¹¶ç§»é¤æ¤å表ç第ä¸ä¸ªå
ç´
System.out.println("After pollFirst():" + linkedList);
linkedList.pollLast(); // è·åå¹¶ç§»é¤æ¤å表çæåä¸ä¸ªå
ç´
System.out.println("After pollLast():" + linkedList);
linkedList.push(2); // å°å
ç´ æ¨å
¥æ¤å表æè¡¨ç¤ºçå æ ï¼æå
¥å°å表ç头ï¼
System.out.println("After push(2):" + linkedList);
linkedList.pop(); // 仿¤å表æè¡¨ç¤ºçå æ å¤å¼¹åºä¸ä¸ªå
ç´ ï¼è·åå¹¶ç§»é¤å表第ä¸ä¸ªå
ç´ ï¼
System.out.println("After pop():" + linkedList);
linkedList.add(3);
linkedList.removeFirstOccurrence(3); // 仿¤å表ä¸ç§»é¤ç¬¬ä¸æ¬¡åºç°çæå®å
ç´ ï¼ä»å¤´é¨å°å°¾é¨éåå表ï¼
System.out.println("After removeFirstOccurrence(3):" + linkedList);
linkedList.removeLastOccurrence(3); // 仿¤å表ä¸ç§»é¤æå䏿¬¡åºç°çæå®å
ç´ ï¼ä»å¤´é¨å°å°¾é¨éåå表ï¼
System.out.println("After removeFirstOccurrence(3):" + linkedList);
/************************** éåæä½ ************************/
System.out.println("-----------------------------------------");
linkedList.clear();
for (int i = 0; i < 100000; i++) {
linkedList.add(i);
}
// è¿ä»£å¨éå
long start = System.currentTimeMillis();
Iterator iterator = linkedList.iterator();
while (iterator.hasNext()) {
iterator.next();
}
long end = System.currentTimeMillis();
System.out.println("Iteratorï¼" + (end - start) + " ms");
// 顺åºéå(éæºéå)
start = System.currentTimeMillis();
for (int i = 0; i < linkedList.size(); i++) {
linkedList.get(i);
}
end = System.currentTimeMillis();
System.out.println("forï¼" + (end - start) + " ms");
// å¦ä¸ç§for循ç¯éå
start = System.currentTimeMillis();
for (Integer i : linkedList)
;
end = System.currentTimeMillis();
System.out.println("for2ï¼" + (end - start) + " ms");
// éè¿pollFirst()æpollLast()æ¥éåLinkedList
LinkedList temp1 = new LinkedList<>();
temp1.addAll(linkedList);
start = System.currentTimeMillis();
while (temp1.size() != 0) {
temp1.pollFirst();
}
end = System.currentTimeMillis();
System.out.println("pollFirst()æpollLast()ï¼" + (end - start) + " ms");
// éè¿removeFirst()æremoveLast()æ¥éåLinkedList
LinkedList temp2 = new LinkedList<>();
temp2.addAll(linkedList);
start = System.currentTimeMillis();
while (temp2.size() != 0) {
temp2.removeFirst();
}
end = System.currentTimeMillis();
System.out.println("removeFirst()æremoveLast()ï¼" + (end - start) + " ms");
}
}
```