1.栈
1.1概念
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。
入栈:栈的插入操作被称作入栈,入栈数据在栈顶
出栈:栈的删除操作被称作出栈,出栈数据在栈顶。
生活实例:子弹上膛,单侧开的羽毛球桶
1.2栈的使用
方法测试:
public class demo {
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
//入栈测试
stack.push(1);
stack.push(2);
stack.push(4);
System.out.println(stack.size());//查看栈内元素个数
System.out.println(stack.peek());//获取栈顶元素
//出栈测试
System.out.println("=================================");
stack.pop();//4出栈
System.out.println(stack.pop());//3出栈
System.out.println(stack.size());//查看栈内元素个数
System.out.println(stack.peek());//获取栈顶元素
System.out.println("=================================");
stack.pop();
if (stack.isEmpty()) {
System.out.println("栈空");
}
System.out.println(stack.size());//查看栈内元素个数
}
}
测试结果:
1.3栈的实现(硬代码实现)
package day_10_18_Stack;
import java.util.Arrays;
public class MyStack {
//定义一个数组去存储数据
private int[] elementData;
private int size;
//定义一下数组的默认大小
private final int DEFAULT_CAPACITY = 3;
//无参初始化
public MyStack() {
//创建一个大小为三的数组
this.elementData = new int[DEFAULT_CAPACITY];
}
//含参初始化
public MyStack(int capacity) {
if (capacity < 0) {
throw new RuntimeException("数组的大小不能小于0");
} else if (capacity > 0) {
this.elementData = new int[capacity];
} else {
this.elementData = new int[DEFAULT_CAPACITY];
}
}
//入栈
public void push(int data) {
//先对数组进行扩容
ensureCapcity();
//将新的数据加入到栈顶
elementData[size] = data;
size++;
}
//出栈
public int pop() {
//获取栈顶
int top = peek();
size--;
return top;
}
public int size() {
return size;
}
//获取栈顶
public int peek() {
if (size == 0) {
throw new RuntimeException("栈为空");
}
int top = elementData[size - 1];//获取栈顶
return top;
}
//判断是否为空
public boolean empty() {
return size == 0;
}
//扩容
public void ensureCapcity() {
if (size == elementData.length) {
this.elementData = Arrays.copyOf(elementData, elementData.length * 2);
}
}
}
测试代码:
package day_10_18_Stack;
public class demo2 {
public static void main(String[] args) {
MyStack stack=new MyStack();
stack.push(1);
stack.push(2);
stack.push(4);
System.out.println(stack.size());//查看栈内元素个数
System.out.println(stack.peek());//获取栈顶元素
//出栈测试
System.out.println("=================================");
stack.pop();//4出栈
System.out.println(stack.pop());//3出栈
System.out.println(stack.size());//查看栈内元素个数
System.out.println(stack.peek());//获取栈顶元素
System.out.println("=================================");
stack.pop();
System.out.println(stack.empty());
}
}
测试结果:
2.队列
2.1概念
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头 (Head/Front)
2.2队列的使用
注意:Queue是个接口,在实例化时必须实例化LinkedList的对象,因为LinkedList实现了Queue接口。
public class demo {
public static void main(String[] args) {
Queue<Integer> queue=new LinkedList<>();
queue.offer(1);
queue.offer(2);
queue.offer(3);
System.out.println(queue.size());
System.out.println(queue.peek());
queue.poll();
queue.poll();
queue.poll();
if(queue.isEmpty()){
System.out.println("队列为空");
};
System.out.println(queue.size());
}
}
测试结果:
2.3队列的实现(硬代码实现)
public class MyQueue {
//结构体定义
private static class ListNode {
int value;
ListNode prev;
ListNode next;
//初始化
public ListNode(int value) {
this.value = value;
}
}
//头节点和尾节点
public ListNode head;
public ListNode tail;
public int size;
//入队
public void offer(int value) {
ListNode node = new ListNode(value);
if (head == null) {
head = node;
tail = node;
} else {
tail.next = node;
node.prev = tail;
}
tail = node;
size++;
}
//出队(从队头出队)
public int poll() {
if (isEmpty()) {
throw new RuntimeException("队列为空,不能出队");
}
int value = head.value;//记录出队的元素值
head = head.next;
if (head == null) {
tail = null;
} else {
head.prev.next = null;//处理出队的节点
head.prev = null;
}
size--;
return value;
}
//判断队列是否为空
public boolean isEmpty() {
return size == 0;
}
//查询队首的值
public int peek() {
if (isEmpty()) {
throw new RuntimeException("队列为空");
}
return head.value;
}
//队列的大小
public int size() {
return size;
}
//输出队列
public void display() {
StringBuilder sb = new StringBuilder();
sb.append("[");
//定义一个遍历节点
ListNode current = head;
while (current != null) {
sb.append(current.value);
if (current.next != null) {
sb.append(",");
}
current = current.next;
}
sb.append("]");
System.out.println(sb);
}
}
测试:
public class demo1 {
public static void main(String[] args) {
MyQueue queue = new MyQueue();
queue.offer(1);
queue.offer(2);
queue.offer(3);
queue.display();
System.out.println("队列大小是" + queue.size());
System.out.println("队列的队头是" + queue.peek());
queue.poll();
queue.poll();
System.out.println("出队两次");
queue.display();
queue.poll();
System.out.println("出队一次");
if (queue.isEmpty()) {
System.out.println("队列为空");
}
;
}
}
测试结果:
2.4双端队列 (Deque)
双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。 那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。
Deque是一个接口,使用时必须创建LinkedList的对象。