java基于数组实现栈(二)

概述

实现上一篇博客中提到的2个点。
上一篇博客中的todo

实现

判断栈是否为空

	/**
     * @return 判断栈是否为空
     */
    private boolean isEmpty() {
        return tail == 0; // tail=0 说明没有进行过push操作(push后tail至少为1)即为空栈
    }

判断栈是否已满

	/**
     * @return 判断栈是否已满
     */
    private boolean isFull() {
        return tail == capacity; // tail的最大值是数组的最后一个元素的索引的下一个索引(即数组长度)即capacity
    }

使用泛型机制定义元素类型

参考完整实现。

完整实现

package com.lovehena.datastructure;

import lombok.extern.slf4j.Slf4j;

/*
 *   基于数组实现栈
 *       核心:将数组最后一个元素的索引视为栈顶(因为 操作数组最后一个元素相对于操作数组第一个元素要简单的多),
 *            出栈、入栈都从栈顶操作
 *   先实现3个方法:
 *       1.将元素压入栈
 *       2.将元素弹出栈
 *       3.遍历栈
 * */
@Slf4j
public class ArrayStack<E> { // 泛型E表示 栈中元素的类型

    private int capacity; // 栈的容量 有界栈

    private int tail = 0; // 类似于链表实现栈中的尾指针

    // 构造器中对栈的容量赋值
    public ArrayStack(int capacity) {
        this.capacity = capacity;
        // 不能这么写 否则会报错 Type parameter 'E' cannot be instantiated directly
        //arr =  new E[capacity];
        arr= (E[]) new Object[capacity];
    }

    private E[] arr = null;

    /**
     * 将元素压入栈
     *
     * @param value 元素的值 元素类型可以设置为Object 也可以利用泛型机制
     * @return
     */
    public boolean push(E value) {
        if (isFull()) {
            log.warn("元素: {} 添加失败 因为栈已满", value);
            return false;
        }
        arr[tail] = value;
        tail++; // tail往后移一位
        log.info("元素: {} 添加成功", value);
        return true;
    }

    /**
     * 将元素弹出栈 并返回被弹出的元素
     * <p>
     * 思路:让tail指向 原来所指的最后一个元素的上一个元素即可 即 忽略原来的最后一个元素(删除最后一个元素)
     * 如 栈为
     * 元素  1 2
     * 索引  0 1 2
     * ↑
     * tail
     * 现在要弹出最后一个元素(removeLast)2 则让tail直接指向1即可(原来所指的最后一个元素的上一个元素)
     * <p>
     * 元素  1 2
     * 索引  0 1 2
     * ↑
     * tail
     * 2被忽略了 即被删除了
     */
    public E pop() {
        if (isEmpty()) { // 空栈
            log.info("栈为空");
            return null;
        }
        E ele = arr[tail - 1];
        // arr[tail - 1] = null; // 删除最后一个元素 我的理解是 是否设置为null都可以
        tail--; // 让tail指向原来的最后一个元素的上一个元素
        return ele;
    }

    /**
     * @return 判断栈是否为空
     */
    private boolean isEmpty() {
        return tail == 0; // tail=0 说明没有进行过push操作(push后tail至少为1)即为空栈
    }

    /**
     * @return 判断栈是否已满
     */
    private boolean isFull() {
        return tail == capacity; // tail的最大值是数组的最后一个元素的索引的下一个索引(即数组长度)即capacity
    }

    public void print() {
        StringBuilder sb = new StringBuilder();
        // 从数组第一个元素开始 直到最后一个元素
        for (int i = 0; i < tail; i++) {
            sb.append(arr[i]).append("\t");
        }
        log.info("遍历栈 栈为:{}", sb.toString());
    }


}

测试用例

	public static void main(String[] args) {
        ArrayStack<Person> stack = new ArrayStack<Person>(2);
        stack.push(new Person("张三","北京",25));
        stack.push(new Person("李四","上海",27));
        stack.print();
        log.info("\n");

        // 尝试再压入一个元素
        stack.push(new Person("赵六","广州",29));
        stack.print();
        log.info("\n");

        // 弹出一个元素
        Person poppedEle = stack.pop();
        log.info("弹出的元素为:{}",poppedEle);
        stack.print();
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    private static class Person{
        private String name; // 姓名
        private String address; // 住址
        private int age; // 年龄

        @Override
        public String toString() {
            return JSONUtil.toJsonStr(this); // 转为json字符串输出 好看些
        }
    }

测试用例输出

测试用例输出

最后

好了,如果对你有帮助的话,欢迎点个免费的赞哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值