(二) 数据结构之栈

  • 栈是一种线性结构
  • 相比数组, 栈对应的操作是数组的子集
  • 只能从一端添加元素, 也只能从一端取出元素
  • 这一端称为栈顶
  • 栈是一种后进先出的数据结构Last In First Out(LIFO)

栈接口

package pers.jssd.stack;

/**
 * 栈的接口
 *
 * @author jssd
 * Create 2019-07-23 8:25
 */
public interface Stack<E> {

   /**
    * 取得栈中的元素个数
    * @return 栈中的元素个数
    */
   int getSize();

   /**
    * 压栈
    * @param e 压栈的元素
    */
   void push(E e);

   /**
    * 退栈
    * @return 退栈的元素
    */
   E pop();

   /**
    * 查看栈顶元素
    * @return 栈顶元素
    */
   E peek();

   /**
    * 判断栈是否为空
    * @return true则栈为空, false则栈不空
    */
   boolean isEmpty();
}

栈的实现

package pers.jssd.stack;

/**
 * 数组栈
 *
 * @author jssd
 * Create 2019-07-23 8:28
 */
public class ArrayStack<E> implements Stack<E> {

   private Array<E> array;

   public ArrayStack() {
      array = new Array<>();
   }

   public ArrayStack(int capacity) {
      array = new Array<>(capacity);
   }

   @Override
   public int getSize() {
      return array.getSize();
   }

   @Override
   public void push(E e) {
      array.addLast(e);
   }

   @Override
   public E pop() {
      return array.removeLast();
   }

   @Override
   public E peek() {
      return array.getLast();
   }

   @Override
   public boolean isEmpty() {
      return array.isEmpty();
   }

   /**
    * 取得数组栈的容量
    * @return 数组栈的容量
    */
   public int getCapacity() {
      return array.getCapacity();
   }

   @Override
   public String toString() {
      return "ArrayStack{" +
            "array=" + array +
            '}' + "<-----TOP";
   }
}

此处用到了数组类

package pers.jssd.stack;

/**
 * @author jssd
 * Create 2019-07-21 8:24
 */
public class Array<E> {
   private E[] data; // 数组的存储数据
   private int size; // 数据实际存储的数据大小

   /**
    * 构造函数, 构造数组的初始容量
    *
    * @param capacity 初始的容量大小
    */
   @SuppressWarnings("unchecked")
   public Array(int capacity) {
      data = (E[]) new Object[capacity];
      size = 0;
   }

   /**
    * 默认构造, 初始容量默认为10
    */
   public Array() {
      this(10);
   }

   /**
    * 取得数组的容量大小
    *
    * @return int 数组的容量
    */
   public int getCapacity() {
      return data.length;
   }

   /**
    * 取得数组存储的数据大小
    *
    * @return 数组存储的数据大小
    */
   public int getSize() {
      return size;
   }

   /**
    * 查看数组是否为空
    *
    * @return 如果为空true, 如果不为空false
    */
   public boolean isEmpty() {
      return size == 0;
   }

   /**
    * 向指定位置添加一个元素
    *
    * @param index 添加元素的位置
    * @param e     要添加的元素
    */
   public void add(int index, E e) {

      if (index < 0 || index > size) {
         throw new IllegalArgumentException("add fall, index is error");
      }
      if (index == data.length) {
         resize(data.length * 2);
      }
      // 将每个元素从index开始, 向后拷贝一个位置
      System.arraycopy(data, index, data, index + 1, size - index);
      data[index] = e;
      size++;
   }

   /**
    * 向末尾添加元素
    *
    * @param e 添加的元素
    */
   public void addLast(E e) {
      add(size, e);
   }

   /**
    * 向开头添加元素
    *
    * @param e 添加的元素
    */
   public void addFirst(E e) {
      add(0, e);
   }

   /**
    * 获取指定位置的元素
    *
    * @param index 获取元素的位置
    * @return 返回获取的指定元素
    */
   public E get(int index) {
      if (index < 0 || index >= size)
         throw new IllegalArgumentException("get fall, index is error");

      return data[index];
   }

   public E getFirst() {
      return get(0);
   }

   public E getLast() {
      return get(size - 1);
   }

   /**
    * 修改指定位置的元素
    *  @param index 修改元素的位置
    * @param e     修改指定元素新的值
    */
   public void set(int index, E e) {
      if (index < 0 || index >= size) {
         throw new IllegalArgumentException("set error, index is error");
      }
      data[index] = e;
   }

   /**
    * 查找元素的索引
    *
    * @param e 查找的元素
    * @return -1如果没有找到, 找到则返回相应的索引
    */
   public int find(E e) {
      for (int i = 0; i < size; i++) {
         if (data[i].equals(e)) {
            return i;
         }
      }
      return -1;
   }

   /**
    * 查看元素在数组中是否存在
    *
    * @param e 查看的元素
    * @return true则元素存在, false则元素不存在
    */
   public boolean contain(E e) {
      int index = find(e);
      return index != -1;
   }

   /**
    * 删除指定位置的元素
    *
    * @param index 要删除的元素位置
    * @return 删除的元素
    */
   public E remove(int index) {
      if (index < 0 || index >= size) {
         throw new IllegalArgumentException("remove fall, index is error");
      }
      E ref = data[index];
      System.arraycopy(data, index + 1, data, index, size - index - 1);
      size--;
      if (size == data.length / 4 && data.length / 2 != 0) {
         resize(data.length / 2);
      }

      return ref;
   }

   /**
    * 删除最后的元素
    *
    * @return 删除的元素
    */
   public E removeLast() {
      return remove(size - 1);
   }

   /**
    * 删除第一个元素
    *
    * @return 删除的元素
    */
   public E removeFirst() {
      return remove(0);
   }

   /**
    * 删除数组中第一次出现的指定元素
    *
    * @param e 删除的元素
    * @return true删除成功, false 删除失败
    */
   public boolean removeElement(E e) {
      int index = find(e);
      if (index != -1) {
         remove(index);
         return true;
      }
      return false;
   }

   /**
    * 删除所有指定的元素
    * @param e 要删除的元素
    * @return 返回删除元素的个数, 如果为0, 则没有删除任何元素
    */
   public int removeAllElement(E e){
      int index = find(e);
      int count = 0;
      while (index != -1) {
         remove(index);
         count ++;
         index = find(e);
      }
      return count;
   }

   /**
    * 对数组进行扩容操作
    * @param newCapacity 新的容量
    */
   @SuppressWarnings("unchecked")
   private void resize(int newCapacity) {
      E[] newData = (E[]) new Object[newCapacity];
      if (size >= 0) System.arraycopy(data, 0, newData, 0, size);
      data = newData;
   }

   @Override
   public String toString() {
      StringBuilder sb = new StringBuilder();
      sb.append("Array: size = ").append(size).append(", capacity = ").append(data.length).append("\n");
      sb.append("[");
      for (int i = 0; i < size; i++) {
         sb.append(data[i]);
         if (i != size - 1) {
            sb.append(", ");
         }
      }
      sb.append("]");

      return sb.toString();
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值