DS02-栈的实现方式之数组实现

本文介绍了栈的先进后出特性,并通过定义Stack接口、Array类以及ArrayStack类,详细阐述了如何使用自定义数组来实现栈的基本操作,包括进栈、出栈、查看栈顶元素和判断栈是否为空。由于操作集中在数组的末尾,所以这些操作的时间复杂度为O(1)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

栈的特点:先进后出,基本操作包括:进栈push,出栈pop,查看栈顶元素peek,判断栈是否为空isEmpty,获取栈中元素的个数getSize
定义一个Stack接口,记下上述操作,定义一个Array类实现自定义的数组类的操作,最后再来一个ArrayStack类,实现Stack接口,复用Array类中的方法就可以轻松实现栈
由于是使用自定义数组类实现的栈,无论是进栈还是出栈,都是只需要对数组类的最后一个元素进行操作,因此进栈/出栈/获取栈顶元素的时间复杂度都为O(1),具体代码如下:
Stack接口

public interface Stack<E> {
	public void push(E e);
	public E pop();
	public E peek();
	public int getSize();
	public boolean isEmpty();
}

数组类

public class Array<E> {
	private E data[];
	private int size;
	
	/**
	 * 构造函数,传入数组的容量capacity构建数组
	 * @param capacity 数组容量
	 */
	public Array(int capacity) {
		this.data = (E[])new Object[capacity];
		size = 0;
	}
	/**
	 * 默认构造方法,容量为10
	 */
	public Array() {
		this(10);
	}
	/**
	 * 获取数组中元素的个数
	 * @return	元素个数
	 */
	public int getSize() {
		return this.size;
	}
	
	/**
	 * 获取数组中的容量大小
	 * @return 容量
	 */
	public int getCapacity() {
		return this.data.length;
	}
	
	/**
	 * 判断数组是否为空
	 * @return 是否为空
	 */
	public boolean isEmpty() {
		return this.size == 0;
	}
	
	/**
	 * 在所有元素后插入一个新的元素e
	 * @param e 要插入的元素
	 */
	public void addLast(E e) {
		add(this.size,e);
	}
	
	/**
	 * 在数组头插入一个元素e
	 * @param e 要插入的元素
	 */
	public void addFirst(E e) {
		add(0,e);
	}
	
	/**
	 * 在指定索引位置插入元素e
	 * @param index 索引值
	 * @param e 元素值
	 */
	public void add(int index,E e) {
		if(this.size >= this.data.length * 0.75) {
			this.reSize(this.data.length * 2);
		}
		/*
		 * if(this.size == this.data.length) { throw new
		 * IllegalArgumentException("参数错误,元素个数大于数组容量"); }
		 */
		if(index < 0 || index > this.size) {
			throw new IllegalArgumentException("参数错误,索引越界");
		}
		for(int i = this.size - 1; i >= index; i--) {
			data[i + 1] = data[i];
		}
		data[index] = e;
		size ++;
	}
	
	/**
	 * 获取指定索引位置的元素值
	 * @param index
	 * @return
	 */
	public E get(int index) {
		if(index < 0 || index >= size) {
			throw new IllegalArgumentException("索引越界");
		}
		return this.data[index];
	}
	
	/**
	 * 获取第一个元素
	 * @return
	 */
	public E getFirst() {
			return get(0);
	}
	
	public E getLast() {
		return get(getSize() - 1);
	}
	
	/**
	 * 设置指定索引位置的元素值为e
	 * @param index
	 * @param e
	 */
	public void set(int index,E e) {
		if(index < 0 || index >= size) {
			throw new IllegalArgumentException("索引越界");
		}
		this.data[index] = e;
	}
	
	/**
	 * 判断数组中是否包含元素e
	 * @param e
	 * @return
	 */
	public boolean contains(E e) {
		for(int i = 0; i < size; i++) {
			if(this.data[i].equals(e)) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 返回查找的元素e的索引值
	 * @param e
	 * @return
	 */
	public int find(E e) {
		for(int i = 0; i < size; i++) {
			if(this.data[i].equals(e)) {
				return i;
			}
		}
		return -1;
	}
	
	/**
	 * 删除数组中指定索引位置的元素,返回被删除的元素
	 * @param index
	 * @return
	 */
	public E remove(int index) {
		if(index < 0 || index >= size) {
			throw new IllegalArgumentException("索引越界");
		}
		if(this.size <= this.data.length / 3) {
			this.reSize(this.data.length / 2);
		}
		E res = data[index];
		for(int i = index; i < size; i++) {
			data[i] = data[i+1];
		}
		data[size] = null;
		size--;
		return res;
	}
	
	/**
	 * 删除数组中的第一个元素,返回被删除的元素
	 * @return
	 */
	public E removeFirst() {
		return remove(0);
	}
	
	/**
	 * 删除数组中最后一个元素,返回被删除的元素
	 * @return
	 */
	public E removeLast() {
		return remove(size - 1);
	}
	
	/**
	 * 删除数组中的元素e
	 * @param e
	 */
	public void removeElement(E e) {
		int index = find(e);
		if(index != -1) {
			remove(index);
		}
	}
	
	private void reSize(int capacity) {
		E[] newData = (E[])new Object[capacity];
		for(int i = 0; i < this.size; i++) {
			newData[i] = this.data[i];
		}
		this.data = newData;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("Array : catacity = " + this.getCapacity() + ", size = " + this.getSize() + "; [ ");
		for(int i = 0; i < size ; i++) {
			sb.append(data[i]);
			if( i != size - 1) {
				sb.append(", ");
			}
		}
		sb.append(" ]");
		return sb.toString();
	}
}

栈类(底层用数组类实现):

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();
	}
	
	@Override
	public void push(E e) {
		array.addLast(e);
	}
	
	@Override
	public E pop() {
		return array.removeLast();
	}
	
	@Override
	public E peek() {
		return array.getLast();
	}
	
	public int getCapacity() {
		return array.getCapacity();
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("Stack : [ ");
		for(int i = 0; i < array.getSize(); i++) {
			sb.append(array.get(i));
			if( i != array.getSize() - 1) {
				sb.append(", ");
			}
		}
		sb.append(" ] top");
		return sb.toString();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值