数据结构与算法—>栈

栈的定义
栈(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);
	}

}
上一篇:机器学习实战:数据预处理之独热编码(One-Hot Encoding)


下一篇:解释器模式