Java Stack面试题

1. 什么是栈(Stack)?

栈是一种后进先出(LIFO)的数据结构,允许在一端进行添加和移除操作。

Stack<Integer> stack = new Stack<>();
stack.push(1); // 添加元素到栈顶
Integer element = stack.pop(); // 移除并返回栈顶元素

2. Java中栈的常用实现有哪些?

Java中栈的常用实现包括Stack类和Deque接口的实现,如ArrayDeque

Stack<Integer> stack = new Stack<>();
Deque<Integer> dequeStack = new ArrayDeque<>();

3. 栈和队列有什么区别?

栈是后进先出(LIFO)的数据结构,而队列是先进先出(FIFO)的数据结构。

4. 栈有什么常见操作?

栈的常见操作包括push(入栈)、pop(出栈)、peek(查看栈顶元素)和isEmpty(检查栈是否为空)。

Stack<Integer> stack = new Stack<>();
stack.push(1); // 入栈
Integer topElement = stack.peek(); // 查看栈顶元素
stack.pop(); // 出栈
boolean isEmpty = stack.isEmpty(); // 检查栈是否为空

5. 如何检查栈是否为空?

可以使用isEmpty方法检查栈是否为空。

Stack<Integer> stack = new Stack<>();
boolean isEmpty = stack.isEmpty();

6. 栈的`peek`方法和`pop`方法有什么区别?

peek方法返回栈顶元素但不移除它,而pop方法移除并返回栈顶元素。

Stack<Integer> stack = new Stack<>();
stack.push(1);
Integer peekElement = stack.peek(); // 返回栈顶元素1,但不移除
Integer popElement = stack.pop(); // 返回并移除栈顶元素1

7. 栈如何实现表达式求值?

可以使用栈来实现算术表达式的求值。

Stack<Integer> stack = new Stack<>();
// 示例:添加数字到栈中
stack.push(3);
stack.push(5);
stack.push(2);

8. 栈如何用于函数调用的实现?

栈用于存储函数调用的信息,如返回地址和参数,这在系统栈或调用栈中很常见。

9. 栈如何实现括号匹配?

可以使用栈来匹配成对的括号,如(){}[]

Stack<Character> stack = new Stack<>();
stack.push('(');
stack.push(')'); // 匹配成功
boolean isMatch = stack.isEmpty(); // 检查栈是否为空

10. 栈如何实现回文检查?

可以使用栈来判断一个字符串是否是回文。

Stack<Character> stack = new Stack<>();
String word = "level";
for (char c : word.toCharArray()) {
    stack.push(c);
}
String reversed = new String(stack.toArray()); // 出栈得到反转字符串
boolean isPalindrome = word.equals(reversed); // 检查是否是回文

11. 栈在数据结构中有什么应用?

栈在数据结构中用于实现递归函数、回溯算法、表达式求值、括号匹配等。

12. 栈是否允许重复元素?

是的,栈允许重复元素。

Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(1); // 允许重复元素

13. 栈的迭代器如何工作?

栈的迭代器可以遍历栈中的元素,但由于栈的特性,通常使用pop方法来访问元素。

Stack<Integer> stack = new Stack<>();
stack.push(1);
Iterator<Integer> iterator = stack.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
    iterator.remove(); // 迭代过程中移除元素
}

14. 栈是否线程安全的?

Stack类不是线程安全的,但可以使用线程安全的Deque实现,如ArrayDeque

Deque<Integer> threadSafeStack = new ArrayDeque<>();
threadSafeStack.push(1);
Integer element = threadSafeStack.pop();

15. 如何使用栈实现其他数据结构?

可以使用栈实现队列和递归函数的调用栈。

// 使用栈实现队列
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
stack1.push(1); // 入队
stack2.push(stack1.pop()); // 出队到另一个栈
Integer element = stack2.pop(); // 队首元素

16. 栈在操作系统中有什么作用?

栈在操作系统中用于存储程序执行期间的局部变量、函数参数和返回地址。

17. 栈如何用于深度优先搜索(DFS)?

栈用于存储深度优先搜索中的节点,以实现非递归的DFS。

Stack<Node> stack = new Stack<>();
stack.push(root); // 从根节点开始
while (!stack.isEmpty()) {
    Node current = stack.pop();
    // 处理当前节点
    for (Node neighbor : current.neighbors()) {
        stack.push(neighbor); // 将邻居节点入栈
    }
}

18. 栈如何用于撤销操作?

栈可以用于实现撤销操作,如文本编辑器中的撤销功能。

Stack<String> undoStack = new Stack<>();
undoStack.push("Action 1"); // 执行操作
// 执行撤销
String lastAction = undoStack.pop();

19. 栈如何用于表达式简化?

栈可以用于简化数学表达式,如去除括号。

20. 栈在编译器设计中的作用是什么?

栈在编译器设计中用于语法分析、词法分析和代码生成。