目录
一、栈
1.1栈的概念
栈是一种特殊的线性表,只允许在固定的一端进行插入和删除数据的操作。进行插入和删除数据的一端叫做栈顶,另外一端叫做栈底。栈中的元素遵循后进先出的原则。
压栈:对数据进行插入的操作叫做压栈。
出栈:对数据进行删除的操作叫做出栈。
1.2栈的使用
栈的几个使用方法:
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
stack.push(1);//压栈
stack.push(2);
stack.push(3);
System.out.println(stack.size());//获取栈中的元素个数——》3个
stack.pop();//出栈
System.out.println(stack.peek());//获取栈顶元素,此时是2
stack.pop();
stack.pop();
//判断栈是否为空,此时元素全部出栈,输出true
System.out.println(stack.empty());
}
1.3栈的模拟实现
从上图中可以看到,
Stack
继承了
Vector
,
Vector
和
ArrayList
类似,都是动态的顺序表,不同的是
Vector
是线程安
全的。
我们可以用数组模拟实现一个栈:
public class MyStack {
public int[] array;
public static final int k = 3;
public MyStack(){
this.array = new int[3];
}
public int usedSize = 0;
//压栈
public int push(int data){
//判满
isFull();
array[usedSize++] = data;
return data;
}
//出栈
public int pop(){
return array[--usedSize];
}
public boolean isEmpty(){
return usedSize == 0;
}
public int peek(){
return array[--usedSize];
}
//判断栈是否满了
public void isFull(){
if(usedSize == array.length){
array = Arrays.copyOf(array,usedSize*2);
}
}
}
1.4栈、虚拟机栈、栈帧有什么区别呢?
栈、虚拟机栈、栈帧有什么区别呢?_栈、虚拟机栈、栈帧有什么区别呢?-CSDN博客
二、队列
2.1队列的概念
队列
:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出
FIFO(First In First Out)
入队列:进行插入操作的一端称为
队尾(
Tail/Rear
)
出队列:进行删除操作的一端称为
队头
(
Head/Front
)
2.2队列的使用
java中,Queue是个接口,底层通过链表来实现
注意:
Queue
是个接口,在实例化时必须实例化
LinkedList
的对象,因为
LinkedList
实现了
Queue
接口。
2.3队列的模拟实现
public class Queue {
// 双向链表节点
public static class ListNode{
ListNode next;
ListNode prev;
int value;
ListNode(int value){
this.value = value;
}
}
ListNode first; // 队头
ListNode last; // 队尾
int size = 0;
// 入队列---向双向链表位置插入新节点
public void offer(int e){
ListNode newNode = new ListNode(e);
if(first == null){
first = newNode;
// last = newNode;
}else{
last.next = newNode;
newNode.prev = last;
// last = newNode;
}
last = newNode;
size++;
}
// 出队列---将双向链表第一个节点删除掉
public int poll(){
// 1. 队列为空
// 2. 队列中只有一个元素----链表中只有一个节点---直接删除
// 3. 队列中有多个元素---链表中有多个节点----将第一个节点删除
int value = 0;
if(first == null){
return null;
}else if(first == last){
last = null;
first = null;
}else{
value = first.value;
first = first.next;
first.prev.next = null;
first.prev = null;
}
--size;
return value;
}
// 获取队头元素---获取链表中第一个节点的值域
public int peek(){
if(first == null){
return null;
}
return first.value;
}
public int size() {
return size;
}
public boolean isEmpty(){
return first == null;
}
}
2.4循环队列
class MyCircularQueue {
private int [] elem;
public int front;//队头
public int rear;//队尾
public MyCircularQueue(int k) {
this.elem = new int[k + 1];
}
public boolean enQueue(int value) {
if(isFull()){
return false;
}
elem[rear] =value;
rear = (rear+1)% elem.length;
return true;
}
public boolean deQueue() {
//出队
if(isEmpty()){
return false;
}
front = (front+1)% elem.length;
return true;
}
public int Front() {
// 得到队头元素
if(isEmpty()){
return -1;
}
return elem[front];
}
public int Rear() {
if(isEmpty()){
return -1;
}
int index = (rear == 0)?elem.length-1:rear-1;
return elem[index];
}
public boolean isEmpty() {
return front == rear;
}
public boolean isFull() {
return (rear+1)% elem.length == front;
}
}
如何区分空与满?
当:rear == front 时为满
当:rear == front 时为空