【数据结构】栈和队列

目录

什么是栈

模拟实现栈

Stack

Stack的方法

 队列

什么是队列

模拟实现队列

Queue

Queue的方法


什么是栈

栈是一种特殊的线性表,它 只允许在固定的一端进行插入和删除元素操作 。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守 先进后出 的原则。

模拟实现栈

通过数组和链表都可以实现栈,下面我们通过数组来实现一个栈。

•栈的属性

    //实现栈的数组
    public int[] elem;
    //栈里元素的有效个数
    public int usedSize;
    //数组的初始大小
    public static final int DEFAULT_SIZE = 10;

•栈的构造方法

    //初始化数组大小
    public MyStack() {
        this.elem = new int[DEFAULT_SIZE];
    }

•入栈方法

    //入栈
    public int push(int val) {
        //判断当前栈是否满了
        if (isFull()) {
            elem = Arrays.copyOf(elem, elem.length * 2);
        }
        //将val值入栈并使有效个数加一
        elem[usedSize++] = val;
        return val;
    }
    //判断当前栈是否满了
    public boolean isFull() {
        return usedSize == elem.length;
    }

•判断当前栈是否为空

    //判断当前栈是否为空
    public boolean empty() {
        return usedSize == 0;
    }

•出栈方法

    public int pop() {
        //判断当前栈是否为空
        if (empty()) {
            throw new MyEmptyStackException("pop():栈为空!");
        }
        //返回栈顶元素并使有效个数减一
        return elem[--usedSize];
    }

自定义异常类:

public class MyEmptyStackException extends RuntimeException {
    public MyEmptyStackException() {

    }
    public MyEmptyStackException(String message) {
        super(message);
    }
}

•获取栈顶元素

    //获取栈顶元素
    public int peek() {
        //判断是否为空
        if (empty()) {
            throw new MyEmptyStackException("peek():栈为空!");
        }
        //返回栈顶元素
        return elem[usedSize-1];
    }

•获取栈的大小

    //获取栈的大小
    public int size() {
        return usedSize;
    }

Stack

Java集合里的stack就是栈,它的底层是通过数组实现的。

通过上图可知,Stack 继承了 Vector( Vector 和 ArrayList 都是动态的顺序表,不同的是Vector是线程安全的) ,故 Stack 也是线程安全的。

Stack 除了包括由 Vector 定义的所有方法,也定义了自己的一些方法。

Stack的方法

方法描述
Stack()构造一个空的栈
Object push(Object element)将elmement元素入栈,并作为此函数的值返回

Object pop()

将栈顶元素出栈,并作为此函数的值返回
Object peek()查看栈顶元素,但不从栈中移除它
int size()
获取栈中有效元素个数
boolean empty()检测栈是否为空
int search(Object element)返回元素在堆栈中的位置,以 1 为基数,先入栈的位置靠后
import java.util.Stack;

public class Test {
    public static void main(String[] args) {
        Stack<Integer> s = new Stack();
        s.push(1);
        s.push(2);
        s.push(3);
        s.push(4);
        System.out.println(s.search(1)); //获取2在栈中的位置--->3
        System.out.println(s.size()); // 获取栈中有效元素个数---> 4
        System.out.println(s.peek()); // 获取栈顶元素---> 4
        s.pop(); // 4出栈,栈中剩余1 2 3,栈顶元素为3
        System.out.println(s.pop()); // 3出栈,栈中剩余1 2 栈顶元素为3
        if (s.empty()) {
            System.out.println("栈空");
        } else {
            System.out.println("栈中剩余元素个数:" + s.size());
        }
    }
}

 队列

什么是队列

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

模拟实现队列

队列同样可以通过数组和链表实现,下面我们一起通过双向链表来实现一个队列。

•链表的节点

    //定义节点
    static class ListNode {
        //节点的值
        int val;
        //指向前一个节点
        ListNode prev;
        //指向后一个节点
        ListNode next;
        //初始化节点的值
        public ListNode(int val) {
            this.val = val;
        }
    }

•列表的属性

    //队头
    ListNode head;
    //队尾
    ListNode tail;
    //有效个数
    int usedSize;

•入队列

    //入队列(尾插)
    public void offer(int val) {
        //实例化一个新节点
        ListNode node = new ListNode(val);
        //尾插法
        if (this.head == null) {
            this.head = node;
            this.tail = node;
        } else {
            this.tail.next = node;
            node.prev = this.tail;
            this.tail = node;
        }
        //有效数字加一
        usedSize++;
    }

•出队列

    //出队列(头出)
    public int poll() {
        int val = 0;
        if (head == null) {
            //队列为空
            return null;
        } else if (this.head == this.tail) {
            //队列中只有一个元素
            val = this.head.val;
            this.head = null;
            this.tail = null;
        } else {
            //队列中有多个元素
            val = this.head.val;
            this.head = this.head.next;
            this.head.prev = null;
        }
        //有效数字减一
        usedSize--;
        //返回被弹出队列的值
        return val;
    }

•查看队头元素

    //查看队头元素
    public int peek() {
        if (head == null) {
            return null;
        }
        return this.head.val;
    }

•获取队列大小

    //获取队列大小
    public int size() {
        return usedSize;
    }

•判断队列是否为空

    //判断队列是否为空
    public boolean isEmpty() {
        return usedSize == 0;
    }

Queue

在Java集合中Queue是个接口,底层是通过双向链表实现的。

由图中可以看成,Queue 和 Deque 都是个接口,故在实例化 Queue 时必须实例化 LinkedList的对象,因为 LinkedList 实现了Queue 接口。

Queue的方法

方法描述
boolean add(E e)将指定的元素插入到此队列中,如果当前没有可用空间,则抛出异常
E element()检索但不删除此队列的头,如果此队列为空,则抛出异常 
E remove()检索并删除此队列的头,如果此队列为空,则抛出异常
boolean offer(E e)将指定的元素插入到此队列中,如果当前没有可用空间,则返回flase
E peek()检索但不删除此队列的头,如果此队列为空,则返回 null
E poll()检索并删除此队列的头,如果此队列为空,则返回 null
int size()
获取队列中有效元素个数
boolean isEmpty()
检测队列是否为空
public class Test {
    public static void main(String[] args) {
        Queue<Integer> q = new LinkedList<>();
        q.offer(1);
        q.offer(2);
        q.offer(3);
        q.offer(4);
        q.offer(5); // 从队尾入队列
        System.out.println(q.size());
        System.out.println(q.peek()); // 获取队头元素
        q.poll();
        System.out.println(q.poll()); // 从队头出队列,并将删除的元素返回
        if(q.isEmpty()){
            System.out.println("队列空");
        }else{
            System.out.println(q.size());
        }
    }
}
 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

记得开心一点啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值