栈的三个操作:
入栈:将元素从栈顶往栈底放;出栈:将栈顶元素删除;取栈顶元素 :获取到最上面的元素。 栈的特点:后进先出。
队列的三个操作:
入队列:从队尾插入元素;出队列:删除队首元素;取队首元素:获取队首位置元素的值。 队列的特点:先进先出。
队列的变种:
优先队列:出队列顺序与入队列顺序不相同,每次出队列元素都是优先级最高的元素。
消息队列:按照“类型”来获取元素。
阻塞队列:队列为空时,出队列操作会受到阻塞;队列满的时候,入队列操作会受到阻塞。
无锁队列:线程安全的队列,比较高效。
栈可以基于顺序表实现,也可以基于链表实现。
public class MyStack {
//基于顺序表实现一个栈
private int[] array = new int[100];
private int size;
//入栈
public void push(int value){
//将value放到数组末尾
array[size] = value;
size++;
}
//出栈
public Integer pop() {
if (size<0) {
return null;
}
int ret = array[size-1];
size--;
return ret;
}
//取栈顶元素
public Integer peek() {
if (size<0) {
return null;
}
return array[size-1];
}
}
public class MyStack2 {
//链表实现栈
static class Node {
public int val;
public Node next;
public Node(int val) {
this.val = val;
}
}
Node head = new Node(-1);
public void push(int val) {
Node cur = new Node(val);
cur.next = head.next;
head.next = cur;
}
public Integer pop() {
Node toDelete = head.next;
if (toDelete==null) {
return null;
}
head.next = toDelete.next;
return toDelete.val;
}
public Integer peek() {
if (head.next==null) {
return null;
}
return head.next.val;
}
}
队列也可以基于链表或顺序表实现。
public class MyQueue {
//链表尾部作为队尾,头部作为队首
static class Node {
public int val;
public Node next;
public Node(int val) {
this.val = val;
}
}
public Node head = new Node(-1);
Node tail = head;
//入队列(尾插)
public void offer(int val) {
Node cur = new Node(val);
tail.next = cur;
tail = tail.next;
}
//出队列(头删)
public Integer poll() {
Node toDelete = head.next;
if (toDelete == null) {
//队列为空,出队列失败
return null;
}
head.next = toDelete.next;
if (head.next == null) {
tail = head;
}
return toDelete.val;
}
//取队首元素
public Integer peek() {
if (head.next == null) {
return null;
}
return head.next.val;
}
}
public class MyQueue2 {
//顺序表实现队列
private int[] array = new int[100];
private int head = 0;
private int tail = 0;
private int size = 0;
public boolean offer(int val) {
if (size == array.length) {
return false;
}
array[tail] = val;
size++;
if (tail>array.length) {
tail = 0;
}
size++;
return true;
}
public Integer poll() {
if (size == 0) {
return null;
}
int ret = array[head];
if (head>=array.length) {
head = 0;
}
size--;
return ret;
}
public Integer peek() {
if (size == 0) {
return null;
}
return array[head];
}
}
两个版本的实现的队列区别:
链表版本的队列:插入元素无上限,效率较低,需要额外内存空间保存引用地址。
顺序表版本的队列:插入元素有上限,效率更高,不需要额外空间。