栈
栈是一种基于后进先出(LIFO)原则的数据结构,它支持两个基本操作:压入(push)和弹出(pop)。在栈中,新元素始终添加在栈顶元素的上方,元素只能从栈顶弹出。
实现方式
栈可以使用数组或链表实现。数组实现的栈称为顺序栈,链表实现的栈称为链式栈。顺序栈的优点是在内存连续的情况下效率高,链式栈的优点是不需要一块连续的内存空间。
基本操作
(1)入栈(push):将元素压入栈顶。
(2)出栈(pop):将栈顶元素弹出。
(3)获取栈顶元素(peek):返回栈顶元素但不弹出。
(4)判空(isEmpty):如果栈为空则返回true,否则返回false。
(5)获取栈中元素个数(size):返回栈中元素的数量。
应用场景
栈广泛应用于计算机系统中,例如函数调用时的存储活动记录、表达式求值、括号匹配、程序执行时的内存分配等。
时间复杂度
栈的入栈、出栈、获取栈顶元素、判空、获取栈中元素个数等基本操作的时间复杂度均为O(1)。
代码实现栈
用于实现栈的基本操作:入栈(push)、出栈(pop)、查看栈顶元素(peek)和判断栈是否为空(isEmpty)等。
public class Stack {
private int[] data;
private int top;
private int size;
public Stack(int size) {
this.size = size;
this.data = new int[size];
this.top = -1;
}
// 入栈操作
public void push(int x) {
if (top == size - 1) {
throw new RuntimeException("Stack overflow");
}
data[++top] = x;
}
// 出栈操作
public int pop() {
if (top == -1) {
throw new RuntimeException("Stack underflow");
}
return data[top--];
}
// 查看栈顶元素
public int peek() {
if (top == -1) {
throw new RuntimeException("Stack is empty");
}
return data[top];
}
// 判断栈是否为空
public boolean isEmpty() {
return (top == -1);
}
}
优缺点
优点:
- 简单易用:栈是一种简单的数据结构,它的操作包括入栈、出栈、查看栈顶元素等,非常容易理解和使用。
- 操作高效:由于栈只允许在栈顶进行操作,因此入栈和出栈的操作时间复杂度均为O(1),非常高效。
- 占用空间小:由于栈的特殊性质,只需要一个指针来指向栈顶元素,因此占用空间很小。
- 有很多应用:栈是一种重要的数据结构,它在程序中有很多应用,比如函数调用、表达式求值、括号匹配等。
缺点:
- 容量固定:栈的容量是固定的,一旦栈满了,就不能再加入新的元素。
- 只支持一端操作:栈只允许在栈顶进行操作,不支持在中间插入或删除元素,因此不适用于所有情况。
- 容易发生栈溢出:由于栈空间有限,当程序递归调用层数过多或者使用过多的局部变量时,容易发生栈溢出。