📅  最后修改于: 2023-12-03 15:08:26.538000             🧑  作者: Mango
堆栈(Stack)是一种常见的数据结构,它具有后进先出(Last In First Out,LIFO)的特点,比如执行函数调用时就可以使用堆栈。在Java中,我们可以使用数组和泛型来实现堆栈。
我们可以使用数组来实现堆栈。不过在Java中,数组是不可变长度的,所以我们需要使用一个变量来记录当前栈顶的位置。
public class Stack<T> {
private T[] data;
private int top;
public Stack(int capacity) {
data =(T[]) new Object[capacity];
top = -1;
}
public boolean isEmpty() {
return top == -1;
}
public boolean isFull() {
return top == data.length - 1;
}
public void push(T value) {
if (isFull()) {
return;
}
data[++top] = value;
}
public T pop() {
if (isEmpty()) {
return null;
}
return data[top--];
}
public T peek() {
if (isEmpty()) {
return null;
}
return data[top];
}
}
在这个例子中,我们使用了泛型 T 来表示栈中存放的数据类型。在构造函数中,我们初始化了一个大小为 capacity 的数组 data,并将 top 设为 -1,表示栈为空。我们还提供了三个方法:isEmpty(),isFull() 和 push()。isEmpty() 方法用于判断栈是否为空;isFull() 方法用于判断栈是否已满;push() 方法用于将元素入栈。在 push() 方法中,我们先进行 isFull() 的判断,如果已满,则不进行入栈操作。如果还有空间,则将 top 加 1,并将指定的元素存放到 data[top] 的位置上。
我们还提供了两个方法 pop() 和 peek()。pop() 方法用于将栈顶元素出栈,并返回该元素;peek() 方法用于返回栈顶元素,但不将其出栈。
在上一个例子中,我们使用了泛型T来表示栈中的元素类型。如果我们想要存放其他类型的元素,那么需要修改代码,并将T替换为其他类型。而泛型可以帮助我们避免这种重复劳动,使代码更加灵活。
public class Stack<E> {
private Object[] data;
private int top;
public Stack(int capacity) {
data = new Object[capacity];
top = -1;
}
public boolean isEmpty() {
return top == -1;
}
public boolean isFull() {
return top == data.length - 1;
}
public void push(E value) {
if (isFull()) {
return;
}
data[++top] = value;
}
public E pop() {
if (isEmpty()) {
return null;
}
return (E) data[top--];
}
public E peek() {
if (isEmpty()) {
return null;
}
return (E) data[top];
}
}
在这个例子中,我们同样使用了泛型,但是泛型 E 只在堆栈中的元素类型上使用,而不是数组的类型。在 push()、pop() 和 peek() 方法中,我们需要将 Object 类型强制转换为 E 类型。
使用数组和泛型可以很容易地实现堆栈。数组实现要在构造函数中初始化,同时需要注意判断栈是否空或满。泛型实现可以更好地适应各种类型的元素。在使用时,我们只需要将元素类型作为泛型参数传入即可。