1、LinkedList概述
1、链表在内存中有什么特点?
链表在内存中不是一个连续的空间。靠前一个记录后一个的地址值,后一个记录前一个的地址值。
2、链表为什么查询慢,增删快?
查询:先要判断你要查的这个元素,是靠头近还是靠尾近。如果是靠头近,那么从第一个开始遍历;如果靠尾近,那么从最后一个开始遍历。
A:多个节点之间,通过地址进行连接。
例如,多个人手拉手,每个人使用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了。
B:查找速度慢:想查找某个元素,需要通过连接的节点,依次往后查找指定的元素。
C:增删速度快:只需要修改连接下一个元素地址即可。
链表结构,因此增删快,查询相对于ArrayList较慢。
2、LinkedList解析
LinkedList内部有一个内部类Node表示节点。LinkedList实际存储的元素就是一个一个的节点。
内部类构造方法:
Node(Node<E> prev, E element, Node<E> next) {
this.item = element; //当前元素
this.next = next; //后一个元素
this.prev = prev; //前一个元素
}
3、特有方法
LinkedList 类中有两个成员 Node<E> first; Node<E> last;
表示记录了开头节点和末尾节点。每一次添加,不管是添加头还是添加尾还是在中间添加。
都是通过前一个记录后一个的地址值,后一个记录前一个的地址值来实现的。
void add(int index, E element) :将元素添加到index索引位置上
E get(int index) :根据index索引获取元素
E remove(int index) :根据index索引删除元素,并将删除的元素返回
remove(object obj);删除元素。返回是否删除成功
E set(int index, E element):将index索引位置的的元素设置为element
void addFirst(E e) :向链表的头部添加元素
void addLast(E e):向链表的尾部添加元素
E getFirst():获取链头的元素,不删除元素
E getLast():获取链尾的元素,不删除元素
E removeFirst():返回链头的元素并删除链头的元素
E removeLast():返回链尾的元素并删除链尾的元素
//如何用ArrayList实现LinkedList效果呢?
addFirst 利用al.add(0, "Q");
addLast 利用al.add("Q");
getFirst 利用al.get(0)
getLast 利用al.get(al.size() - 1)
removeFirst 利用al.remove(0)
removeLast 利用al.remove(al.size()-1)
以上方法中get,remove(object obj) E remove(int index),实现原理类似,解析:
Node<E> node(int index) {
//先判断索引是离头近还是离尾近
if (index < (size >> 1)) { //离头近
Node<E> x = first;
for (int i = 0; i < index; i++)//从头开始遍历
x = x.next; //将遍历得到的都赋值给变量x。最终遍历到指定索引。将指定索引的值返回
return x;
} else {//离尾近
Node<E> x = last;
for (int i = size - 1; i > index; i--)//从尾开始遍历
x = x.prev; //将遍历得到的都赋值给变量x。最终遍历到指定索引。将指定索引的值返回
return x;
}
}