Java数据结构:栈和队列
栈和队列是Java编程中最常用的两种数据结构类型。它们都代表着一种线性数据结构,其中元素被按照线性的顺序存储,且每个元素只有一个前继和一个后继。栈和队列之间的主要区别在于元素添加和移除的位置以及顺序。本文将从多个角度分析Java数据结构中的栈和队列。
栈的基本概念和实现
栈是一个简单的数据结构,它遵循“后进先出”(LIFO)的原则。栈中插入和删除元素只发生在一个端点,通常称为栈顶。Java中的栈通常用数组或链表来实现。使用数组实现栈通常是最简单的方法,因为数组在Java中的表现形式非常优秀。当元素被推入栈中时,它们被放置在栈的顶部,从而成为新的栈顶。当元素从栈中弹出时,它们从栈顶被删除。下面是一段用数组实现栈的Java代码:
```
public class Stack {
private int maxSize;
private int[] stackArray;
private int top;
public Stack(int s) {
maxSize = s;
stackArray = new int[maxSize];
top = -1;
}
public void push(int j) {
stackArray[++top] = j;
}
public int pop() {
return stackArray[top--];
}
public int peek() {
return stackArray[top];
}
public boolean isEmpty() {
return (top == -1);
}
public boolean isFull() {
return (top == maxSize - 1);
}
}
```
队列的基本概念和实现
队列和栈非常相似,因为它们都是线性数据结构。但与栈不同的是,队列遵循“先进先出”(FIFO)的原则。这意味着,最先被插入队列的元素将首先被删除,而最后插入的元素将被保留在队列中。在Java中,队列可以使用数组或链表来实现。这里,我们提供的是使用链表实现队列的Java代码:
```
public class Queue {
private Node first; // 指向队列的开头
private Node last; // 指向队列的末尾
private class Node {
Object item;
Node next;
}
public boolean isEmpty() {
return first == null;
}
public void enqueue(Object item) {
Node oldlast = last;
last = new Node();
last.item = item;
last.next = null;
if (isEmpty()) first = last;
else oldlast.next = last;
}
public Object dequeue() {
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
Object item = first.item;
first = first.next;
if (isEmpty()) last = null;
return item;
}
}
```
栈和队列的比较
在实际编程中,很难说哪种数据结构比另一种更优越,因为每种数据结构都有不同的优点和缺点。在下面的表格中,我们将比较栈和队列之间的一些差异。
| 特征 | 栈 | 队列 |
| ---- | ---- | ---- |
| 插入和删除操作 | 在栈的顶部进行 | 在队列的末尾进行 |
| 实现方式 | 可以使用数组或链表实现 | 可以使用数组或链表实现 |
| 数据事实上的存储 | 后进先出 | 先进先出 |
| 功能 | 主要用于函数调用和数据结构的反转 | 常用于模拟现实生活的情形,如排队等 |
栈的例子
栈在编程中的用途非常广泛。以下是两个使用栈的示例:
1. 浏览器的后退操作
当你在浏览器中点击“返回”按钮时,浏览器实际上是在访问一个记录在栈中的历史记录。这个历史记录称为“后退堆栈”,因为这些页面是通过先进后出的方式记录的。
2. 括号匹配
在编程的某些领域中,如编译器设计、计算机语言解析和表达式计算等,括号匹配是一项很重要的任务。利用栈,我们可以轻松地验证括号序列中是否有匹配的括号。以下是括号匹配的Java代码:
```
public boolean isBalanced(String expression) {
Stack
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
if (c == '(') s.push(c);
if (c == ')') {
if (s.isEmpty()) return false;
s.pop();
}
}
return s.isEmpty();
}
```
队列的例子
队列在现实生活中有很多应用,例如排队。以下是两个使用队列的示例:
1. 火车站排队
对于需要从火车站购票的人们来说,队列是一种推荐的排队方法。然而,如果没有足够的窗口或后台工作人员,火车站会比较拥挤,因此,需要引入队列来管理人流量。
2. 广度优先搜索
广度优先搜索是一种图形算法,它以一种基于队列的方式遍历每个节点。它首先探索图形的第一层节点,然后是第二层,以此类推,直到找到目标节点。以下是广度优先搜索的伪代码:
```
public void bfs(Node start) {
Queue
q.enqueue(start);
start.visited = true;
while (!q.isEmpty()) {
Node node = q.dequeue();
for (Node neighbour : node.neighbours) {
if (!neighbour.visited) {
q.enqueue(neighbour);
neighbour.visited = true;
}
}
}
}
```
结论
栈和队列都是Java编程中最常用的数据结构类型之一。它们都代表线性数据结构,但栈遵循LIFO的原则,而队列遵循FIFO的原则。在实际编程中,栈和队列有着许多应用。根据应用场景的不同,我们可以选择使用栈或队列来存储、管理和操作数据。
关键字:Java、数据结构、栈、队列
微信扫一扫,领取最新备考资料