JAVA-栈Stack和Deque

一、栈(Stack)的概念

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

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据存储在栈顶

出栈:栈的删除操作叫做出栈。出数据在栈顶

说这么多其实就是一个数组,只要用尾插尾删操作进行增删

 

栈在现实生活中的例子:

弹夹也是先按进去的最后打出去

二、栈的使用

2.1 Stack

这个数据结构非常简单也就这几个方法:

方法的使用:

public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        //分别压入5个数据
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.push(5);

        System.out.println(stack.size());//计算栈中有几个元素,返回5
        System.out.println(stack.pop());//出栈,5
        System.out.println(stack.pop());//出栈,4
        System.out.println(stack.peek());//获取顶层元素3
        System.out.println(stack.peek());//获取顶层元素3

        //栈为空返回true,不为空返回false
        System.out.println(stack.empty());//false
}

2.2 实现Stack

之前说了其实栈就是数组,所以我们用数组来维护。但并非说其他结构如链表不能实现

public class MyStack2<E> {
    public Object[] elem;//泛型需要用Object创建数组
    public int usedSize;//记录元素个数

    public MyStack2() {
        this.elem = new Object[10];
    }
}

2.2.1 push

 public void push(E e) {
        //判断堆栈是否满了
        if(isFull()) {
            //利用此方法可以实现拷贝源数据同时扩容
            elem = Arrays.copyOf(elem,usedSize * 2);
        }

        //useSize刚好可以做为尾插的下标,
        //元素类型是Object所以存放元素的时候最好转一下型
        elem[usedSize] = (E)e; 
        usedSize++;
}



//需要一个判断是否栈满的方法
public boolean isFull() {
        return elem.length == usedSize;
}

2.2.2 pop

public E pop() {
        //判断堆栈是否为空
        try {
            if(empty()) {
                throw new MyStackEmptyException("堆栈为空");
            }
        }catch (MyStackEmptyException e) {
            e.printStackTrace();
        }
        //注意:取元素就一定要强转了,不是 《最好强转》 了
        E ret = (E)elem[usedSize-1];
        usedSize--;
        return ret;
}

 当栈为空还要删除肯定是不行的,写一个异常来处理

public class MyStackEmptyException extends RuntimeException {
    public MyStackEmptyException(String s) {
        super(s);
    }
    public MyStackEmptyException() {
        super();
    }
}

 2.2.3 peek

public E peek() {
        //判断堆栈是否为空
        try {
            if(empty()) {
                throw new MyStackEmptyException("堆栈为空");
            }
        }catch (MyStackEmptyException e) {
            e.printStackTrace();
        }

//      int ret = elem[usedSize-1];
//      usedSize--;
        return (E)elem[usedSize-1];
}

这个不需要多久,不进行删除操作就行了

2.2.4 size

public int size() {
   return usedSize;
}

2.2.5 empty

public boolean empty() {
     if(usedSize == 0) {
         return true;
     }else {
         return false;
     }
}

从上图中可以看到,Stack继承了Vector,Vector和ArrayList类似,都是动态的顺序表,不同的是Vector是线程安 的。

Stack继承了Vector,但是Vector已经过时了,Stack用的也比较少了,但并非不能用。

那我们其实还可以用Deque做为栈使用 

2.3 Deque

//用ArrayDeque实现的栈,背后是数组
Deque<Integer> stack1 = new ArrayDeque<>();
//用LinkdList实现的栈,背后是双向链表
Deque<Integer> stack2 = new LinkedList<>();

当然他们两不只可以用来实现栈,还可以实现队列……

使用方法基本都是一样的:

public static void main(String[] args) {
        Deque<Integer> stack1 = new ArrayDeque<>();
        stack1.push(1);
        stack1.push(2);
        stack1.push(3);
        stack1.push(4);
        stack1.push(5);

        System.out.println(stack1.pop());//5
        System.out.println(stack1.peek());//4
        System.out.println(stack1.peek());//4
        System.out.println(stack1.size());//4
        //Stack中是empty效果是一样的
        System.out.println(stack1.isEmpty());//false

        Deque<Integer> stack2 = new LinkedList<>();

        stack2.push(1);
        stack2.push(2);
        stack2.push(3);
        stack2.push(4);

        System.out.println(stack2.pop());//4
        System.out.println(stack2.peek());//3
        System.out.println(stack2.peek());//3
        System.out.println(stack2.size());//3
        //Stack中是empty效果是一样的
        System.out.println(stack2.isEmpty());//false

}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值