链表 Linked List
- 链表是一种真正的动态数据结构
- 最简单的动态数据结构
- 更深入的理解引用
- 更深入的理解递归
- 辅助组成其他数据结构
- 数据存储在结点中
- 结点对象包括元素e和数据引用next
- 链表结构
实现真正的动态,不需要处理固定容量的问题,但丧失了随机访问的能力。
链表和数组的对比
数据结构 | 适用范围 | 优点 |
---|
链表 | 不适合用于索引有语意的情况 | 动态 |
数组 | 最好用于索引有语意的情况 | 支持快速查询 |
添加元素
- 头部添加元素
- 中间添加元素
找到待添加节点的前一个结点
public class LinkedList<E> {
private class Node{
public E e;
public Node next;
public Node(E e, Node next){
this.e = e;
this.next = next;
}
public Node(E e){
this(e, null);
}
public Node(){
this(null, null);
}
}
private Node head;
private int size;
public LinkedList(){
head = null;
size = 0;
}
public void addFirst(E e){
Node node = new Node(e);
node.next = head;
head = node;
size++;
}
public void add(int index, E e){
if(index < 0 || index > size)
throw new IllegalArgumentException("Add failed. Illegal index.");
if(index == 0)
addFirst(e);
else{
Node prev = head;
for(int i = 0 ; i < index - 1 ; i ++)
prev = prev.next;
Node node = new Node(e);
node.next = prev.next;
prev.next = node;
size ++;
}
}
}
获取更新元素
public E get(int index){
Node cur = dummyHead.next;
for(int i = 0 ; i < index ; i ++)
cur = cur.next;
return cur.e;
}
删除元素
public E remove(int index){
Node prev = dummyHead;
for(int i = 0 ; i < index ; i ++)
prev = prev.next;
Node retNode = prev.next;
prev.next = retNode.next;
retNode.next = null;
size --;
return retNode.e;
}
链表的时间复杂度分析
操作 | 时间复杂度 |
---|
addLast(e) | O(n) |
addFirst(e) | O(1) |
add(index,e) | O(n/2)=O(n) |
removeLast(e) | O(n) |
removeFirst(e) | O(1) |
removeElement(index,e) | O(n/2)=O(n) |
set(index,e) | O(n) |
get(index) | O(n) |
增 | O(n) |
删 | O(n) |
改 | O(n) |
查 | O(n) |