数组

数组的特性

  • 线性表
  • 连续的内存空间和相同的数据类型
  • 下标从0开始
  • 超过下标则出现下标越界异常
  • 数据类型相同

数组的优势

  • 下标的随机访问性能高 O(1)

数组的劣势

  • 插入删除中间元素效率低
  • 不支持动态扩容

链表

缓存淘汰策略:

  • 先进先出FIFO(First In,First Out)
  • 最少使用策略LFU (Least Frequently Used)
  • 最近最少使用LRU (Least Recently Used)

链表的特性:

  • 链表通过指针将一组零散的内存块串联在一起

链表的优点:

  • 指定位置的插入和删除效率高
  • 无大小限制,天然支持动态扩容

链表的缺点:

  • 链表随机访问的性能没有数组好,需要 O(n) 的时间复杂度。
  • 地址不连续,对CPU缓存不友好

链表的分类:

  • 单链表
  • 循环链表
  • 双向链表

链表的应用:

  • LinkedHashMap 底层使用了双向链表

栈:

栈既可以用数组来实现,也可以用链表来实现。用数组实现的栈,我们叫作顺序栈,用链表实现的栈,我们叫作链式栈。

队列

数组实现的队列叫作顺序队列,用链表实现的队列叫作链式队列

循环队列

数组实现的队列往往需要数据迁移,可以用循环队列解决

循环队列队列为空判断条件为headtail
循环队列队列满的时候判断条件为**(tail+1)%n
head**

循环队列代码:

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);
}
}
}