栈的定义
栈(stack)是限定仅在表尾进行插入和删除操作的线性表。(很多类似的原件,比如Word、Photoshop等文档或图像编辑软件,都有撤销功能,就是用栈来实现的。)
我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈,栈就是后进先出,先进后出的线性表。特殊之处在限制了插入和删除的位置,始终只能在栈顶进行,意味着:栈底是固定的,最新进栈的只能在最下面。
栈的插入操作,叫做进栈,也称压栈,入栈。类似子弹入弹夹。
栈的删除操作,也叫出栈或者弹栈。如子弹出弹夹。
栈接口Stack的实现:
int getSize() 获取大小
boolean isEmpty() 判断是否为空
void push(E e)进栈一个元素
E pop()出栈一个元素
E peek()获取当前栈顶 (不移除)
void clear()清空当前栈
/**
*Stack是栈的接口
*
*/
public interface Stack<E> {
/**
* 获取栈中元素个数
*/
public int getSize();
/**
* 是否为空
* @return 是否为空的布尔值
*/
public boolean isEmpty();
/**
* 进栈一个元素e
* e 即将进栈的元素
*/
public void push(E e);
/**
* 出栈一个元素
* @return 当前出栈的栈顶元素
*/
public E pop();
/**
* 获取当前栈顶元素
*
* @return 当前栈顶元素,不弹栈
*/
public E peek();
public void clear();
}
ArrayStack的实现
import com.openlab.xianxingbiao.Arraylist
public class ArrayStack<E> implements Stack<E> {
private ArrayList<E> list;
/**
* 创建默认大小的栈
*/
public ArrayStack() {
list = new ArrayList<E>();
}
/**
* 创建指定容量大小的栈
* @param capacity
*/
public ArrayStack(int capacity) {
list = new ArrayList<E>(capacity);
}
@Override
public int getSize() {
return list.getSize();
}
@Override
public boolean isEmputy() {
return list.isEmputy();
}
@Override
public void push(E e) {
list.addLast(e);
}
@Override
public E pop() {
return list.removeLast();
}
@Override
public E peek() {
return list.getLast();
}
@Override
public void clear() {
list.clear();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("ArrayStack:size="+getSize()+",capaicty="+list.getCapacity()+"\n");
if(isEmputy()) {
sb.append("[]");
}else {
sb.append('[');
for(int i=0;i<getSize();i++) {
sb.append(list.get(i));
if(i==getSize()-1) {
sb.append(']');
}else {
sb.append(',');
}
}
}
return sb.toString();
}
}
双端栈
定义:将一个线性表的两端当做栈底进行入栈和出栈操作————如下图
双端栈的实现
package com.openlab.zhan;
import java.awt.List;
import java.time.temporal.IsoFields;
public class ArrayStackDoubleEnd<E> implements Stack<E> {
enum Direction{
LEFT,RIGHT;
}
private E[] data; //用于存储数据的容器
private int leftTop; // 左端栈的栈顶,开始在-1
private int rightTop; // 右端栈的栈顶,开始在data.length
private static int DEFAULT_SIZE = 10; //默认大小为10
public ArrayStackDoubleEnd() {
this(DEFAULT_SIZE);
}
public ArrayStackDoubleEnd(int capacity) {
data = (E[]) new Object[capacity];
leftTop = -1;
rightTop = data.length;
}
private boolean isFull() {
return leftTop+1 == rightTop;
}
//向指定的端口进栈元素
public void push(Direction dir,E e) {
if( isFull()) {
}
if(dir == Direction.LEFT) {
data[++leftTop] = e;
}else {
data[--rightTop] = e;
}
private void resize(int newlen) {
E[] newData = (E[]) new Object[newlen];
for(int i = 0;i<=leftTop;i++) {
newData[i] = data[i];
}
}
}
//从指定的端口出栈
public E pop (Direction dir) {
if(dir ==Direction.LEFT) {
if(leftTop ==-1) {
throw new IllegalArgumentException("左端栈为空");
}
return data[leftTop--];
}else {
if(dir== Direction.RIGHT) {
throw new IllegalArgumentException("右端栈为空");
}return data[rightTop++];
}
}
public E peek(Direction dir) {
if(dir ==Direction.LEFT) {
if(leftTop ==-1) {
throw new IllegalArgumentException("左端栈为空");
}
return data[leftTop];
}else {
if(dir== Direction.RIGHT) {
throw new IllegalArgumentException("右端栈为空");
}return data[rightTop];
}
}
//获取指定端口栈的元素个数
public int getSize(Direction dir) {
if(dir ==Direction.LEFT) {
return leftTop-1;
}else {
return data.length - rightTop;
}
}
//判断指定端口是否为空
public boolean isEmpty(Deprecated dir) {
if(dir ==Direction.LEFT) {
return leftTop = -1;
}else {
return rightTop = data.length;
}
return false;
}
public void clear(Direction dir) {
}
/**
* 获取左端栈和右端栈元素的总和
*
*/
@Override
public int getSize() {
return getSize(Direction.LEFT)+getSize(Direction.RIGHT);
}
/**
* 判断左端栈和右端栈是否全为空
*/
@Override
public boolean isEmpty() {
return isEmpty(Direction.LEFT)&&isEmpty(Direction.RIGHT);
}
/**
* 哪端少进哪端
*/
@Override
public void push(E e) {
if(isFull()) {
}
if(getSize(Direction.LEFT)<=getSize(Direction.RIGHT)){
push(Direction.LEFT,e);
}else {
push(Direction.RIGHT,e);
}
}
/**
* 哪端多弹哪段
*/
@Override
public E pop() {
if(isEmpty()) {
throw new IllegalArgumentException("左端为空");
}
if(isFull()) {
}
if(getSize(Direction.LEFT)>getSize(Direction.RIGHT)){
return pop (Direction.LEFT);
}else {
return pop(Direction.RIGHT);
}
}
/**
* 哪端多获取哪端,一样多默认左
*/
@Override
public E peek() {
if(isEmpty()) {
throw new IllegalArgumentException("双栈为空");
}
if(isFull()) {
}
if(getSize(Direction.LEFT)>getSize(Direction.RIGHT)){
return pop (Direction.LEFT);
}else {
return pop(Direction.RIGHT);
}
}
/**
* 左右两端都清空
*/
@Override
public void clear() {
clear(Direction.LEFT);
clear(Direction.RIGHT);
}
}