什么是链表?
什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。
链接的入口节点称为链表的头结点也就是head。
如图所示:
链表的类型:
单链表:一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。
双链表:一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。
循环链表:首尾相连的链表
链表的储存方式:
数组在内存中是连续分布的,而链表在内存中可以不是连续分布的。
链表是通过指针链接在内存中的各个节点。
所以链表中的节点在内存中不是连续分布的,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。
链表和数组的特点:
数组:
数组可以更方便的遍历查找所需要的数据,而在添加或者删除数据的操作时,变得复杂。
链表:
由于链表的特性,链表在一些操作中更加高效,例如删除和插入数据。
链表在内存中不是连续储存的,所以可以充分利用内存中的碎片空间,
链表的缺点就是在搜索的时候必须遍历节点。
以下情况使用 数组 :
- 频繁访问列表中的某一个元素。
- 只需要在列表末尾进行添加和删除元素操作。
以下情况使用 链表 :
- 你需要通过循环迭代来访问列表中的某些元素。
- 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。
JAVA链表(LinkedList)
LinkedList 继承了 AbstractSequentialList 类。
LinkedList 实现了 Queue 接口,可作为队列使用。
LinkedList 实现了 List 接口,可进行列表的相关操作。
LinkedList 实现了 Deque 接口,可作为队列使用。
LinkedList 实现了 Cloneable 接口,可实现克隆。
LinkedList 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。
在java中使用链表(LinkedList):
LinkedList 类位于 java.util 包中,使用前需要引用它,语法格式:
//引入LinkedList 类
import java.util.LinkedList;
//普通创建方式
LinkedList<E> list = new LinkedList<E>();
//使用集合创建链表
LinkedList<E> list = new LinkedList(Collection<? extend E > c);
创建一个简单的链表实例:
import java.util.LinkedList;
public calss Main {
public static void mian (String[] args) {
LinkedList<Sting> arr = new LinkedList<String> ();
arr.add("1");
arr.add("2");
arr.add("3");
arr.add("4");
arr.add("5");
System.out.println(arr);
}
}
运行结果为:[1, 2, 3, 4, 5]
在结尾添加元素:
链表名.addLast(想要添加的元素);
在开头删除元素:
链表名.removeFirst(想要删除的元素);
同理:
使用 removeLast() 移除尾部元素
使用 removeFirst() 移除头部元素
使用 getFirst() 获取头部元素
使用 getLast() 获取尾部元素
遍历元素:
我们可以使用 for 配合 size() 方法来迭代列表中的元素:
// 引入 LinkedList 类
import java.util.LinkedList;
public class Main {
public static void main(String[] args) {
LinkedList<String> arr = new LinkedList<String>();
arr.add("苹果");
arr.add("梨");
arr.add("香蕉");
arr.add("菠萝");
for (int size = arr.size(), i = 0; i < size; i++) {
System.out.println(arr.get(i));
}
}
}
输出结果:[苹果, 梨, 香蕉, 菠萝]
也可以使用 for-each 来迭代元素:
// 引入 LinkedList 类
import java.util.LinkedList;
public class Main {
public static void main(String[] args) {
LinkedList<String> arr = new LinkedList<String>();
arr.add("苹果");
arr.add("梨");
arr.add("香蕉");
arr.add("菠萝");
for (String i : arr) {
System.out.println(i);
}
}
}
输出结果相同
LinkedList更多方法:
public boolean add(E e) | 链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
public void add(int index, E element) | 向指定位置插入元素。 |
public boolean addAll(Collection c) | 将一个集合的所有元素添加到链表后面,返回是否成功,成功为 true,失败为 false。 |
public boolean addAll(int index, Collection c) | 将一个集合的所有元素添加到链表的指定位置后面,返回是否成功,成功为 true,失败为 false。 |
public void addFirst(E e) | 元素添加到头部。 |
public void addLast(E e) | 元素添加到尾部。 |
public boolean offer(E e) | 向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
public boolean offerFirst(E e) | 头部插入元素,返回是否成功,成功为 true,失败为 false。 |
public boolean offerLast(E e) | 尾部插入元素,返回是否成功,成功为 true,失败为 false。 |
public void clear() | 清空链表。 |
public E removeFirst() | 删除并返回第一个元素。 |
public E removeLast() | 删除并返回最后一个元素。 |
public boolean remove(Object o) | 删除某一元素,返回是否成功,成功为 true,失败为 false。 |
public E remove(int index) | 删除指定位置的元素。 |
public E poll() | 删除并返回第一个元素。 |
public E remove() | 删除并返回第一个元素。 |
public boolean contains(Object o) | 判断是否含有某一元素。 |
public E get(int index) | 返回指定位置的元素。 |
public E getFirst() | 返回第一个元素。 |
public E getLast() | 返回最后一个元素。 |
public int indexOf(Object o) | 查找指定元素从前往后第一次出现的索引。 |
public int lastIndexOf(Object o) | 查找指定元素最后一次出现的索引。 |
public E peek() | 返回第一个元素。 |
public E element() | 返回第一个元素。 |
public E peekFirst() | 返回头部元素。 |
public E peekLast() | 返回尾部元素。 |
public E set(int index, E element) | 设置指定位置的元素。 |
public Object clone() | 克隆该列表。 |
public Iterator descendingIterator() | 返回倒序迭代器。 |
public int size() | 返回链表元素个数。 |
public ListIterator listIterator(int index) | 返回从指定位置开始到末尾的迭代器。 |
public Object[] toArray() | 返回一个由链表元素组成的数组。 |
public T[] toArray(T[] a) | 返回一个由链表元素转换类型而成的数组。 |