数组
数组的特性
- 线性表
- 连续的内存空间和相同的数据类型
- 下标从0开始
- 超过下标则出现下标越界异常
- 数据类型相同
数组的优势
- 下标的随机访问性能高 O(1)
数组的劣势
- 插入删除中间元素效率低
- 不支持动态扩容
链表
缓存淘汰策略:
- 先进先出FIFO(First In,First Out)
- 最少使用策略LFU (Least Frequently Used)
- 最近最少使用LRU (Least Recently Used)
链表的特性:
- 链表通过指针将一组零散的内存块串联在一起
链表的优点:
- 指定位置的插入和删除效率高
- 无大小限制,天然支持动态扩容
链表的缺点:
- 链表随机访问的性能没有数组好,需要 O(n) 的时间复杂度。
- 地址不连续,对CPU缓存不友好
链表的分类:
- 单链表
- 循环链表
- 双向链表
链表的应用:
- LinkedHashMap 底层使用了双向链表
栈:
栈既可以用数组来实现,也可以用链表来实现。用数组实现的栈,我们叫作顺序栈,用链表实现的栈,我们叫作链式栈。
队列
数组实现的队列叫作顺序队列,用链表实现的队列叫作链式队列
循环队列
数组实现的队列往往需要数据迁移,可以用循环队列解决
循环队列队列为空判断条件为headtail
循环队列队列满的时候判断条件为**(tail+1)%nhead**
循环队列代码:
public class CircularQueue {
private String[] items;
private int head = 0;
private int tail = 0;
private int capacity = 0;
public CircularQueue(int capacity) {
items = new String[capacity];
this.capacity = capacity;
}
public boolean enqueue(String item) {
//队列是否满了,提前做了判断、如果用tail==head判断这样又和判断空一样了,
// 我们必须舍弃最后一个位置的元素不存储元素,环形队列又是不完美的环
boolean full = (tail +1) % capacity == head;
if (full) {
return false;
}
items[tail] = item;
tail = (tail + 1) % capacity;
return true;
}
public String dequeue() {
boolean empty = head == tail;
if (empty) {
return null;
}
String item = items[head];
head = (head + 1) % capacity;
return item;
}
public static void main(String[] args) {
CircularQueue circularQueue = new CircularQueue(5);
for (int i = 0; i < 10; i++) {
boolean enqueue = circularQueue.enqueue(i + "");
System.out.println("enqueue:" + i + ":result:" + enqueue);
}
for (int i = 0; i < 10; i++) {
String dequeue = circularQueue.dequeue();
System.out.println("dequeue:" + i + ":result:" + dequeue);
}
}
}