JAVA基于静态数组实现栈的基本原理与用法详解

  

JAVA基于静态数组实现栈的基本原理与用法详解

1.概述

在计算机科学中,栈是一种常见的数据结构。栈数据结构可以看作是一个后进先出(LIFO)的数据容器。元素进入栈的顺序是后进先出,也就是说,最新的元素插入的位置在所有其他元素的顶部,而删除并返回的元素始终是当前元素中的“顶部”元素。本文主要介绍基于静态数组实现栈的基本原理与用法。

2.静态数组

静态数组就是指长度固定的数组,数组的长度在初始化时已经确定,无法进行动态扩展。使用静态数组可以在编程中较为方便地处理数据,同时可以在空间上高效利用存储。

3.栈的实现

我们可以利用静态数组来实现栈数据结构。在这里,我们设定了一个栈数组 stack,一个栈顶指针 top,以及栈的最大容量 MAX_SIZE。使用栈的过程中,向栈顶插入元素,我们需要将 top 指针向上移动一个位置。删除栈顶元素时,我们将 top 指针向下移动一个位置。

下面是我们实现栈的基本步骤:

  1. 定义静态数组。

java
private int[] stack;

  1. 定义栈顶指针。

java
private int top;

  1. 定义栈的最大容量。

java
private int MAX_SIZE;

  1. 初始化数组和栈顶指针。

java
// 初始化函数
public StaticArrayStack(int capacity){
stack = new int[capacity]; // 定义大小为 capacity 的静态数组
top = -1; // 栈顶指针初始化为 -1,表示栈为空
MAX_SIZE = capacity; // 将栈的容量设为 capacity
}

  1. 实现栈的基本操作,包括 push()pop() 函数。push() 函数用于向栈中插入元素,pop() 函数则用于弹出栈顶元素。

```java
// 定义 push 函数,向栈中插入元素
public boolean push(int data){
// 判断栈是否已满
if(top == MAX_SIZE - 1){
System.out.println("Stack is full");
return false;
}
else{
top++; // 将栈顶指针向上移动一个位置
stack[top] = data; // 向栈中插入元素
return true;
}
}

// 定义 pop 函数,弹出栈顶元素
public int pop(){
// 判断栈是否为空
if(top == -1){
System.out.println("Stack is empty");
return Integer.MIN_VALUE;
}
else{
int data = stack[top]; // 取出栈顶元素
top--; // 将栈顶指针向下移动一个位置
return data;
}
}
```

  1. 实现其他栈操作,包括 isEmpty() 函数和 isFull() 函数。

```java
// 定义 isEmpty 函数,判断栈是否为空
public boolean isEmpty(){
return top == -1;
}

// 定义 isFull 函数,判断栈是否已满
public boolean isFull(){
return top == MAX_SIZE - 1;
}
```

4.示例

示例1

下面是一段示例代码,展示了如何使用上述栈数据结构进行括号匹配。代码可读性较好,同时也简单易懂。

public class ParenthesisMatching {
    public static boolean match(String expr){
        StaticArrayStack stack = new StaticArrayStack(expr.length());
        for(int i = 0; i < expr.length(); i++){
            char ch = expr.charAt(i);
            if(ch == '(' || ch == '[' || ch == '{'){
                stack.push(ch);
            }
            else if((ch == ')' && !stack.isEmpty() && stack.topElement() == '(') || (ch == ']' && !stack.isEmpty() && stack.topElement() == '[') || (ch == '}' && !stack.isEmpty() && stack.topElement() == '{')){
                stack.pop();
            }
            else{
                return false;                
            }
        }
        return stack.isEmpty();
    }

    public static void main(String[] args){
        System.out.println(match("[(a+b)*(c+d)]"));  // 输出 true
        System.out.println(match("[(a+b)*(c+d])"));  // 输出 false
    }
}

示例2

下面是一个示例,展示了如何使用上述栈数据结构进行滑动窗口问题的解决。给定一个数组和一个整数 k,计算每个滑动窗口的最大值。

public class WindowSliding {
    public static int[] getMaxFromWindow(int[] arr, int k){
        int[] res = new int[arr.length - k + 1];
        StaticArrayStack stack = new StaticArrayStack(arr.length);
        int top = -1;
        for(int i = 0; i < arr.length; i++){
            while(!stack.isEmpty() && stack.topElement() < i - k + 1){
                stack.pop();
            }
            while(!stack.isEmpty() && arr[stack.topElement()] < arr[i]){
                stack.pop();
            }
            stack.push(i);
            if(i >= k - 1){
                res[++top] = arr[stack.topElement()];
            }
        }
        return res;
    }

    public static void main(String[] args){
        int[] arr = {1, 3, -1, -3, 5, 3, 6, 7};
        int k = 3;
        int[] res = getMaxFromWindow(arr, k);
        System.out.println(Arrays.toString(res));  // 输出 [3, 3, 5, 5, 6, 7]
    }
}

在这个示例中,我们使用栈来处理滑动窗口问题。每个元素入栈之前会先将滑动窗口以外的元素从栈中弹出。然后,再将从左到右的较小元素删除。这个示例的时间复杂度为 O(n),因为每个元素入栈并弹出了恰好一次。

相关文章