栈
本篇文章也是我学习网课而总结的一篇博文,网课地址链接《玩转算法系列–玩转数据结构》。
先给个链接基于数组的数组类、自己编写一个链表结构,是本篇博文中数组类引用的依据。
栈是一种后进先出的数据结构,在生活中有许多这样的场景:例如我们平时使用的word、excel、ps等软件,都有撤销操作;简单来说这种场景,就是一种栈的实现方式。
由于栈是一种后进先出的数据结构,因此栈有栈顶的说法,此种数据结构的操作主要集中在栈顶。
接下来,我们使用数组类和链表分别实现栈。
使用数组实现栈
- 定义Stack接口,规范方法及变量
- 沿用我们编写的Array类
- 创建基于Array实现Stack接口的实现类,实现其方法
因为数组类在数组尾部的操作都是O(1)的,因为我们就将栈顶和数组类的尾部相结合,使我们的栈的操作也是O(1);
定义Stack接口,主要是定义获取大小、是否为空、获取栈顶、删除栈顶、加入栈顶的方法。
/**
* 名称:stack接口
* 阐述:
*
* @author Administrator
* @date 2020/2/28 0:32
*/
public interface Stack<E> {
int getSize();
boolean isEmpty();
void push(E e);
E pop();
E peek();
}
实现数组栈
/**
* 名称:数组栈
* 阐述:基于数组类实现栈功能
*
* @author Administrator
* @date 2020/2/28 0:38
*/
public class ArrayStack<E> implements Stack<E> {
private Array<E> array;
public ArrayStack(int capacity){
array = new Array<>(capacity);
}
public ArrayStack(){
array = new Array<>();
}
@Override
public int getSize(){
return array.getSize();
}
@Override
public boolean isEmpty(){
return array.isEmpty();
}
public int getCapacity(){
return array.getCapacity();
}
/**
* 添加到栈顶
* @param e
*/
@Override
public void push(E e){
array.addLast(e);
}
/**
* 删除栈顶元素
* @return
*/
@Override
public E pop(){
return array.removeLast();
}
/**
* 获取栈顶元素
* @return
*/
@Override
public E peek(){
return array.getLast();
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
res.append("Stack: ");
res.append('[');
for(int i = 0 ; i < array.getSize() ; i ++){
res.append(array.get(i));
if(i != array.getSize() - 1){
res.append(", ");
}
}
res.append("] top");
return res.toString();
}
}
用链表实现栈
- 定义Stack接口,规范方法及变量
- 沿用我们编写的LinkedList类
- 创建基于LinkedList实现Stack接口的实现类,实现其方法
在实现中,我们需要理解一点:链表是使用指向的、链表在头部操作的时间复杂度是O(1)的,因此我们在利用链表实现栈的时候,要和数组反过来。
/**
* 名称:
* 阐述:
*
* @author Administrator
* @date 2020/2/28 1:02
*/
public class LinkedListStack<E> implements Stack<E> {
private LinkedList<E> list;
public LinkedListStack(){
list = new LinkedList<>();
}
@Override
public int getSize(){
return list.getSize();
}
@Override
public boolean isEmpty(){
return list.isEmpty();
}
/**
* 获取栈顶的元素(获取链表第一个元素)
* @param e
*/
@Override
public void push(E e){
list.addFirst(e);
}
/**
* 删除栈顶的元素(删除链表的第一个元素)
* @return
*/
@Override
public E pop(){
return list.removeFirst();
}
/**
* 添加栈顶的元素(添加链表的第一个元素)
* @return
*/
@Override
public E peek(){
return list.getFirst();
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
res.append("Stack: top ");
res.append(list);
return res.toString();
}
}
栈的应用
根据栈的特点,有很多的应用;
此时我们可以根据LeetCode中的题库,我们就能大概了解栈常用的应用场景;
在此特别推荐大家去LeetCode中学习和做题,不仅仅是面试,其实也是为了学习。
LeetCode