栈的顺序存储结构

栈的顺序存储结构

栈的定义:

栈是限定仅在表尾进行插入和删除操作的线性表
	 - 我们吧允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom) 		
	 - 不含任何元素的栈称为空栈 		
	 - 栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构
	 -  栈本身时一个线性表,其数据元素具有线性关系,只不过它是一种特殊的线性表而已
	 - 定义中说的是在线性表的表尾进行插入和删除操作,这里表尾是指栈顶,而不是栈底
	 - 栈的插入操作,叫做进栈,也称压栈、入栈
	 - 栈的删除错做,叫做出栈、弹栈
Stack的定义含义@reruen返回值@parm参数
int getSize获取栈中元素的个数栈中的元素个数
boolean isEmpty()判断 栈是否为空是否为空的boolean值
void push(E e)进栈一个元素e 即将进栈的元素
E pop()弹栈一个元素当前出栈的元素
E peek()获取当前栈顶(不移除)当前栈顶的元素 不弹栈
void clear清空

栈的顺序存储结构ArrayStack的定义

ArrayStack的定义含义@reruen返回值@parm参数
ArrayStack()创建一个默认的大小的栈(顺序表
ArrayStack(int capacity)创建一个容量为指定capacity大小的栈(顺序表)
getSize()获取栈中元素的个数list.getSize()
isEmpty ()判断 栈是否为空list.isEmpty
push(E e)进栈元素elist.addLast(e)
E pop()出栈元素elist.removeLast()
E peek()查找当前栈顶(不移除)list.getLast()
clear()清空栈list.clear()
public boolean equals(Object obj){
	return list.equals(obj);
}

在栈中(Object obj)中obj是栈,而 list.equals(obj)中list是顺序表,这里直接拿栈和顺序表去比较了。
obj不能直接获取list,因为子类对象指向父类引用(多态)
多态的情况下不能获取子类的特有行为,只能访问父类

public boolean equals(Object obj){
	if(obj==null){   //先比较空
		return fasle;
	}
	if(obj==this){    //在比较自己
		return true;
     }
     if(obj instanceof ArrayStack){  //你属于一个栈
     	ArrayStack stack=(ArrayStack)obj;  //强转obj成栈
     	return list.equals(stack.list);  //list标志栈当前的list   stack.list:传进来的栈内部的list
     }
     return false;
}
 public String toString() {
		StringBuilder sb=new StringBuilder();//StringBuilder没锁,快
		
		//每次都显示现在的有效个数,和最大容量
		sb.append("ArrayStack: size="+getSize()+",capacity="+list.getCapacity()+"\n");
		if(isEmpty()){
			sb.append("[]");
		}else{
			sb.append('[');
			for(int i=0;i<getSize();i++){    //list.size不再list的内部,不能访问
				sb.append(list.get(i));
				if(i==getSize()-1){   //到了最后一个时
					sb.append(']');
				}else{
					sb.append(',');//用","拼接的时候会产生好多字符串,所以改用','
				}
			}
		}
		return sb.toString();
	}
public class Main{
	public static void main(String[] args){
		ArrayStack<Integer> stack=new ArrayStack<Integer>();
		for(int i=0;i<=10;i++){
			stack.push(i);          //元素进栈
		}
		System.out.println(stack);  // [1,2,3,4,5,6,7,8,9,10]
	}
		for(int i=1;i<=5;i++){
			System.out.println(stack.pop());  //元素出栈
		}
		System.out.println(stack);  // [1,2,3,4,5]
		
		ArrayStack<Integer> stack2=new ArrayStack<Integer>();
		stack2.push(1);     //创建另外一个栈
		stack2.push(2);
		stack2.push(3);
		stack2.push(4);
		stack2.push(5);
		System.out.println(stack.equals(stack2)); // true
}

双端栈的顺序存储结构

定义:

是指将一个线性表的俩端当作栈底分别进行入栈和出栈的操作

不能用ArrayList的实现,因为ArrayList里面只有一个size来表示栈顶,而双端栈ArrayStackDoubeEnd有俩个栈顶。

重新定义

public class ArrayStackDoubleEnd<E> implements stack<E>{

	enum Direction{ //枚举 ,定义一个类型叫Direction只能存储俩个值LEFT,RIGHT
		LEFT,RIGHT;
	}
	private E[] data ;   //用于存储数据的容器
	private int leftTop;  //左端栈的栈顶 开始在-1
	private int rightTop;  //右端的栈顶 开始在data.length
	private static int DEFAUL_SIZE=10; //默认容量大小为10

	public ArrayStackDoubleEnd() {
		this(DEFAULT_SIZE);
	}
	public ArrayStackDoubleEnd(int capacity) {
		data=(E[]) new Object[capacity];
		leftTop=-1;
		rightTop=data.length;
	}
}
ArrayStackDoubeEnd的定义含义@reruen返回值 @parm参数
ArrayStackDoubleEnd()创建一个默认的大小的栈
ArrayStackDoubleEnd(int capacity)创建一个容量为指定capacity大小的栈
void push(Direction dir,E e)向指定的端口进栈元素
E pop(Direction dir)从指定得到端口出栈元素
E Peek(Direction dir)从指定的端口获取元素
getSIize(Direction dir)获取指定端口栈的元素个数
isEmpty(Direction dir)判断指定端口的栈是否为空
clear(Directon dir)清空指定端口的栈
getSize()获取左端栈和右端栈元素的总和getSize(Direction.LEFT)+getSize(Direction.RIGHT)
isEmpty ()判断 左端栈和右端栈是否全为空isEmpty(Direction.LEFT)&&isEmpty(Direction.RIGHT)
push(E e)哪端少哪端进栈元素e
push(E e)哪端少哪端进栈元素e
E pop()哪端多弹栈哪端元素epop(Direction.LEFT)
E pop()哪端多弹栈哪端元素epop(Direction.RIGHT)
E peek()哪端多获取哪端当前栈顶元素(一样多,默认右)peek(Direction.LEFT)
E peek()哪端多获取哪端当前栈顶元素(一样多,默认右)peek(Direction.RIGHT)
clear()左右俩端都清空
clear()左右俩端都清空

判断栈是否已满

private boolean isFull() {   
		return leftTop+1==rightTop;  
	}

向指定的端口进栈元素

public void push(Direction dir,E e) {
		if(isFull()) {
			resize(data.length*2);   //扩容
		}
		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];
		}
		int index=data.length-1;//右端复制  
		int i;
		for( i=newData.length-1;i>newData.length-data.length+rightTop;i--) {//双指针
			newData[i]=data[index--];
		}
		rightTop=i+1;
		data=newData;
	}
	

从指定得到端口出栈元素

public E pop(Direction dir) {
		if(dir==Direction.LEFT) { //左端
			if(leftTop==-1) { //抛异常
				throw new IllegalArgumentException("左端栈为空:");
			}
			if(getSize()<=data.length/1&&data.length>DEFAULT_SIZE) {
				resize(data.length/2);  //缩容
			}
			return data[leftTop--]; //元素被取走。top--:往前退一格
		}else {
			if(rightTop==data.length) {  //右端,抛异常
				throw new IllegalArgumentException("右端栈为空:");
			}
			if(getSize()<=data.length/1&&data.length>DEFAULT_SIZE) {
				resize(data.length/2); //缩容
			}
			return data[rightTop++]; 元素被取走。top++:往后退一格
		}
	}

从指定得到端口获取栈顶元素

public E peek(Direction dir) {
		if(dir==Direction.LEFT) {
			if(leftTop==-1) {
				throw new IllegalArgumentException("左端栈为空:");
			}
			return data[leftTop];
		}else {
			if(rightTop==data.length) {
				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(Direction dir) {
		if(dir==Direction.LEFT) {
			return leftTop==-1;
		}else {
			return rightTop==data.length;
		}
	}

清空指定端口的栈

public void clean(Direction dir) {
		if(dir==Direction.LEFT) {
			leftTop=-1;
		}else {
			 rightTop=data.length;
		}
	}

拼接

public String toString() {
		StringBuilder sb=new StringBuilder();//StringBuilder没锁,快
		
		//每次都显示现在的有效个数,和最大容量
		sb.append("ArrayStack: size="+getSize()+",capacity="+data.length+"\n");
		if(isEmpty()){  //双端空
			sb.append("[]");
		}else{
			sb.append('[');
			int count=0;
			for(int i=0;i<=leftTop;i++) { //左边的遍历
				sb.append(data[i]);
				count++;  //每进一个元素记录一次
				if(count==getSize()) { //当count=有效数字的时候
					sb.append(']');
				}else {
					sb.append(',');
				}
			}
			for(int i=rightTop;i<data.length;i++) { //右边的遍历
				sb.append(data[i]);
				count++;
				if(count==getSize()) {
					sb.append(']');
				}else {
					sb.append(',');
				}
			}
		}
		return super.toString();
	
	}
	

比较

public boolean equals(Object obj) { //纯粹比较俩个双端栈的内容
		if(obj==null){
			return false;
		}
		if(obj==this){
			return true;
		}
		if(obj instanceof ArrayStackDoubleEnd) { //属于一个栈
			ArrayStackDoubleEnd<E>  stack=(ArrayStackDoubleEnd) obj;//创建一个传入栈stack,并进行强转
			if(getSize()==stack.getSize()) {
				ArrayList<E> list1=new ArrayList<E>(getSize());
				ArrayList<E> list2=new ArrayList<E>(getSize());
				
				for(int i=0;i<=leftTop;i++) { //将左边的数拼接到当前栈的左部分
					list1.addLast(data[i]);
				}
				for(int i=rightTop;i<data.length;i++) { //拼接当前栈的右部分
					list1.addLast(data[i]);
				}
				for(int i=0;i<=stack.leftTop;i++) { //拼接传入栈的左部分
					list2.addLast(stack.data[i]);
				}
				for(int i=stack.rightTop;i<stack.data.length;i++) { //拼接传入栈的右部分
					list2.addLast(stack.data[i]);
				}
				return list1.equals(list2);
			}
		}
		return false;
	}

枚举的概述:
枚举是在一定范围内取值,并且这个值必须是枚举类型中的任意一个,并且只能有一个
特点:
1.必须在规定范围内取值
2.这个值只能取一个
3.这个值可以是规定范围内的任意一个枚举的本质就是一个Java类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值