栈和队列

栈是线性表的一种,只允许在栈顶进行插入或者删除的一种数据结构,栈中的数据遵循先进后出或者说是后进先出的原则

  • 出栈:对数据进行删除操作
  • 入栈:对数据进行插入操作,入栈也叫做压栈
  • 栈只有一个口,所以入栈出栈的操作都是在栈顶实现的
  • 在 Java 集合中,栈是一个接口,可用顺序表和链表实现
  • 在插入和删除数据时,我们可以认为是尾插/尾删操作,而对于顺序表来说,这种操作更容易实现,所以我们用顺序表来实现栈
import java.util.Arrays;

public class MyStack {
    private int[] arr;
    int size;

    public MyStack(int defaultCapacity){
        arr = new int[defaultCapacity];
        size = 0;
    }
    public MyStack(){
        this(20);
    }

    //插入操作
    public void push(int element){
        if(size==arr.length){//说明栈已经存储满
            arr = Arrays.copyOf(arr,arr.length*2);//扩容
        }
        //为什么不是arr[++size] = element;
        //我们这里用数组实现栈
        //数组下标是从 0 开始存储的
        arr[size++] = element;
    }
    //删除操作
    public void pop(int element){
        if(size<=0){
            System.out.println("无法删除,栈为空");
            return;
        }
        size--;
    }
    //返回栈顶元素
    public int top(){
        if(size<=0){
            System.out.println("栈为空,无法返回栈顶元素");
            return -1;
        }
        return arr[size-1];
    }
    //判断栈是否为空
    public boolean isEmpty(){
        return size==0;
    }
    //栈有多少元素
    public int size(){
        return size;
    }
}

队列

队列只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特点

  • 入队列:进行插入操作的一端称为队尾(Tail/Rear)
  • 出队列:进行删除操作的一端称为队头(Head/Front)

在这里插入图片描述
队列也可以用顺序表和链表实现,如果用顺序表实现,进行删除操作时,需要将数组元素都进行移动,而链表直接让 head = head.next,相对来说,链表更容易实现,我们用链表模拟队列的实现在这里插入图片描述

class Node{
    int val;
    Node next = null;

    public Node(int val){
        this.val = val;
    }
}

public class MyQueue {
    private Node front = null;
    private Node rear = null;
    int size = 0;

    //队尾插入元素
    public void offer(int val){
        Node node = new Node(val);
        if(rear==null){
            front = node;
        }else{
            rear.next = node;
        }
        rear = node;
        size++;
    }

    //队头删除元素
    public void poll(){
        if(size==0){
            System.out.println("队列为空,无法删除");
            return;
        }
        front = front.next;
        if(front==null){
            rear = null;
        }
        size--;
    }
    //返回队首元素
    public int peek(){
        if(size==0){
            System.out.println("队列为空,无队首元素");
        }
        return front.val;
    }
    //判断队列是否为空
    public boolean isEmpty(){
        return size==0;
    }
    //队列有多少元素
    public int size(){
        return size;
    }
}

循环队列

循环队列顾名思义就是队尾元素的下一个元素是队首元素,循环队列通常用数组实现
在这里插入图片描述

在这里插入图片描述
假如说要在队尾后面继续存放3个元素,那么最后一个元素的下标是多少?
i = (index + 3)%arr.length = (6+3)%7 = 2,所以在下标为 2 的位置上,通过观察,我们也确实发现在下标为 2 的位置上

如何区分队空和队满

在这里插入图片描述
队空:Q.rear==Q.front;
队满:(Q.rear + 1)%arr=front;

双端队列

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。

Java 中的栈和队列

Stack

方法解释
E push (E item)压栈
E pop ()出栈
E peek ()获取栈顶元素
boolean empty ()判断栈是否为空
import java.util.Stack;

public class StackDemo {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<>();
        stack.push("我");
        stack.push("爱");
        stack.push("小");
        stack.push("年");
        System.out.println(stack);
        System.out.println(stack.empty());//false
        System.out.println(stack.peek());//年
        System.out.println(stack.pop());//年
        System.out.println(stack.pop());//小
        System.out.println(stack.pop());//爱
        System.out.println(stack.pop());//我
        System.out.println(stack.empty());//true
    }
}
//执行结果
[,,,]
false
年
年
小
爱
我
true

Queue

方法解释
offer (e)入队列
poll ()出队列
peek ()获取队首元素
import java.util.LinkedList;
import java.util.Queue;

public class QueueDemo {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();
        queue.add("我");
        queue.add("爱");
        queue.offer("小");
        queue.offer("年");
        System.out.println(queue);
        System.out.println(queue.isEmpty());//false
        System.out.println(queue.poll());//我
        System.out.println(queue.peek());//爱
        System.out.println(queue.element());//爱
        System.out.println(queue.remove());//爱
        System.out.println(queue.remove());//小
        System.out.println(queue.poll());//年
        System.out.println(queue.isEmpty());//true
    }
}
//执行结果
[,,,]
false
我
爱
爱
爱
小
年
true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值