一、Stack 概述

  1、Stack 是栈结构,它继承与 Vector。它的特性是:先进后出(FILO,First In Last Out)或 后进先出(LIFO,Last In First Out);

  2、Stack是Vector的子类,比Vector多了几个方法,它的后进先出的特征,就是通过调用这几个方法实现的。

  3、

  4、

  5、

二、Stack 结构

  1、Stack 类声明

public class Stack<E> extends Vector<E>

    可以发现 Stack 是 Vector 的子类。

  2、Stack 类继承结构

    

 

  3、

  4、

三、Stack 创建

  1、构造器

    源码:

1 public Stack() {}

 

    Stack 只提供了一个无参的构造器,但是这里会调用父类的构造器:

1 public Vector() {
2     this(10);
3 }

    可以发现,在这里创建了一个长度为10的数组。

 

  2、添加元素

    通过 Stack 的 push() 方法,可以向栈中添加元素,本质还是调用父类 Vector 的 addElement() 方法:

1 public synchronized void addElement(E obj) {
2      modCount++;
3      ensureCapacityHelper(elementCount + 1);
4      elementData[elementCount++] = obj;
5 }

 

    可以发现,如果需要进行扩容的话也是调用 vector 中的扩容方式来扩容的,即容量扩容为原来的2倍。

 

  3、

四、Stack 方法

  1、方法列表

    

  2、push(E) 方法

    把元素压入栈顶,等价于add(item),这里为了更形象化,单独设计了一个push。

    源码:

 1     public E push(E item) {
 2         addElement(item);
 3 
 4         return item;
 5     }
 6     // 调用 Vector 的 addElement() 方法
 7     public synchronized void addElement(E obj) {
 8         modCount++;
 9         ensureCapacityHelper(elementCount + 1);
10         elementData[elementCount++] = obj;
11     }

     在JDK9 中:

    

     然后调用 Vector 中的 add 方法:

    

 

  3、pop() 方法:弹出栈顶元素

    源码:

 1 public synchronized E pop() {
 2     E       obj;
 3     int     len = size();
 4 
 5     obj = peek();
 6     removeElementAt(len - 1);
 7 
 8     return obj;
 9 }
10 
11 // 调用 Vector 的removeElementAt()方法
12 public synchronized void removeElementAt(int index) {
13     modCount++;
14     if (index >= elementCount) {
15         throw new ArrayIndexOutOfBoundsException(index + " >= " +
16                                                  elementCount);
17     }
18     else if (index < 0) {
19         throw new ArrayIndexOutOfBoundsException(index);
20     }
21     int j = elementCount - index - 1;
22     if (j > 0) {
23         System.arraycopy(elementData, index + 1, elementData, index, j);
24     }
25     elementCount--;
26     elementData[elementCount] = null; /* to let gc do its work */
27 }

 

  4、peek() 方法:获取栈顶元素,不移除

    源码:

 1 public synchronized E peek() {
 2     int     len = size();
 3 
 4     if (len == 0)
 5         throw new EmptyStackException();
 6     return elementAt(len - 1);
 7 }
 8 
 9 public synchronized E elementAt(int index) {
10     if (index >= elementCount) {
11         throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
12     }
13 
14     return elementData(index);
15 }
16 
17 E elementData(int index) {
18     return (E) elementData[index];
19 }

 

  5、empty() 方法

    源码:

1 public boolean empty() {
2     return size() == 0;
3 }

 

  6、search(Object) 方法:返回的是从栈顶开始计算索引位置的

    源码:

 1 public synchronized int search(Object o) {
 2     int i = lastIndexOf(o);
 3 
 4     if (i >= 0) {
 5         return size() - i;
 6     }
 7     return -1;
 8 }
 9 
10 public synchronized int lastIndexOf(Object o) {
11     return lastIndexOf(o, elementCount-1);
12 }
13 
14 public synchronized int lastIndexOf(Object o, int index) {
15     if (index >= elementCount)
16         throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
17 
18     if (o == null) {
19         for (int i = index; i >= 0; i--)
20             if (elementData[i]==null)
21                 return i;
22     } else {
23         for (int i = index; i >= 0; i--)
24             if (o.equals(elementData[i]))
25                 return i;
26     }
27     return -1;
28 }

 

 

五、案例

  1、数组模拟栈一

 1 class ArrayStack {
 2     private int[] data;   //存储数据
 3     private int size;    //元素的个数
 4 
 5     //默认容量
 6     private static final int DEFAULT_CAPACITY = 10;
 7 
 8     ArrayStack() {
 9         data = new int[DEFAULT_CAPACITY];
10     }
11 
12     ArrayStack(int capacity) {
13         data = new int[capacity];
14     }
15 
16     //把item压入堆栈顶部
17     public void push(int ele) {
18         //判断是否需要扩容
19         if (size > data.length) {
20             data = Arrays.copyOf(data, data.length * 2);
21         }
22         data[size++] = ele;
23     }
24 
25     //查看堆栈顶部的对象,但不从堆栈中移除它
26     public int peek() {
27         if (size == 0) {
28             throw new EmptyStackException();
29         }
30         return data[size-1];  //获取栈顶元素
31     }
32 
33     //移除堆栈顶部的对象,并作为此函数的值返回该对象
34     public int pop() {
35         int o = this.peek();       //获取栈顶元素
36         size--;                    //减少元素个数
37         return o;
38     }
39 
40     //返回对象在栈中的位置,以 1 为基数,从栈顶开始计算
41     public int search(int ele) {
42         //顺着放倒着拿(FILO/LIFO)
43         for (int i = size - 1; i >=0; i--)
44         {
45             if (ele == data[i]) {
46                 return size - i;
47             }
48         }
49         return -1;    //返回栈中不存在该元素
50     }
51 
52     public int size() {
53         return size;
54     }
55 
56     //测试堆栈是否为空
57     public boolean empty() {
58         return size == 0;
59     }
60 }

 

  2、数组模拟栈二

 1 /**
 2  *  定义一个ArrayStack 表示栈
 3  */
 4 public class MyArrayStack {
 5     private int maxSize;    // 栈的大小
 6     private int[] stack;    // 数组,数组模拟栈,数据就在该数组中
 7     private int top = -1;   // top 表示栈顶,初始化为 -1
 8 
 9     // 构造器
10     public MyArrayStack(int maxSize) {
11         this.maxSize = maxSize;
12         stack = new int[this.maxSize];
13     }
14 
15     // 判断栈满
16     public boolean isFull() {
17         return top == maxSize - 1;
18     }
19 
20     // 判断栈空
21     public boolean isEmpty() {
22         return top == -1;
23     }
24 
25     // 入栈 - push
26     public void push(int value) {
27         // 先判断栈是否满
28         if (isFull()) {
29             System.out.println("栈满");
30             return;
31         }
32         top++;
33         stack[top] = value;
34     }
35 
36     // 出栈 - pop,将栈顶的数据返回
37     public int pop() {
38         // 先判断栈是否空
39         if (isEmpty()) {
40             // 抛出异常来处理
41             throw new RuntimeException("栈空,没有数据··");
42         }
43         int value = stack[top];
44         top--;
45         return value;
46     }
47 
48     // 显示栈的情况[遍历栈],从栈顶往下显示数据
49     public void list() {
50         if (isEmpty()) {
51             System.out.println("栈空,没有数据~~");
52             return;
53         }
54 
55         for (int i = top; i >= 0; i--) {
56             System.out.printf("stack[%d]=%d\n", i, stack[i]);
57         }
58     }
59 }

 

 

 

posted on 2021-04-19 10:38  格物致知_Tony  阅读(195)  评论(0编辑  收藏  举报