01-栈
01-栈
标准库中的栈
Stack:
Stack<Integer> s = new Stack<>();push() , pop() , peek()
JDK官方文档不建议使用Stack实现栈的功能,转而使用Deque接口的ArrayDeque实现栈的功能
Deque继承自Queue, Stack继承自Vector, Deque即“double ended queue”缩写;
Deque具备普通队列FIFO功能,同时具备StackLIFO功能;
ArrayDeque没有容量限制,可以作为栈来使用,效率高于Stack;
ArrayDeque也可以作为队列来使用,效率相较于基于双向链表的LinkedList也要更好一些;
算法题中的栈
1 2 3 4 5
Deque<Integer> stack = new ArrayDequeue<Integer>(); stack.push(i); stack.pop(); stack.peek();
数组模拟栈
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package stack;
import java.util.Scanner;
public class ArrayStackDemo {
public static void main(String[] args) {
ArrayStack stack = new ArrayStack(4);
String key = "";
boolean loop = true;
Scanner scanner = new Scanner(System.in);
while(loop) {
System.out.println("show:显示栈");
System.out.println("exit:退出程序");
System.out.println("push:入栈");
System.out.println("pop:出栈");
key = scanner.next();
switch(key) {
case "show":
stack.list();
break;
case "push":
System.out.println("请输入一个数");
int value = scanner.nextInt();
stack.push(value);
break;
case "pop":
try {
int res = stack.pop();
System.out.printf("出栈的数据为:%d\n",res);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case "exit":
scanner.close();
loop = false;
break;
}
}
}
}
class ArrayStack{
private int maxSize; //栈的大小
private int[] stack;
private int top = -1;
//构造器
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
stack = new int[this.maxSize];
}
//栈满
public boolean isFull() {
return top == maxSize - 1;
}
//栈空
public boolean isEmpty() {
return top == -1;
}
//入栈-push
public void push(int value) {
if(isFull()) {
System.out.println("栈满");
return;
}
top++;
stack[top] = value;
}
//出栈-pop
public int pop() {
if(isEmpty()) {
throw new RuntimeException("栈空");
}
int value = stack[top];
top--;
return value;
}
//遍历栈,从栈顶开始显示
public void list() {
if(isEmpty()) {
System.out.println("栈空");
return;
}
for(int i = top;i>=0;i--) {
System.out.printf("stack[%d]=%d\n",i, stack[i]);
}
}
}
使用栈计算表达式
中缀表达式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package stack;
public class Calculator {
public static void main(String[] args) {
String expression = "12*5-9+10";
ArrayStack2 numStack = new ArrayStack2(10);
ArrayStack2 operStack = new ArrayStack2(10);
int index = 0; //用于扫描
int num1 = 0;
int num2 = 0;
int oper = 0;
int res = 0;
char ch = ' ';
String keepNum = ""; //用于拼接多位数
while(true) {
ch = expression.substring(index, index+1).charAt(0);
//根据ch进行相应从处理
if(operStack.isOper(ch)) {//如果是运算符
if(!operStack.isEmpty()) {
if(operStack.priority(ch)<=operStack.priority(operStack.peek())) {
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.cal(num1, num2, oper);
//运算结果入数栈
numStack.push(res);
//当前操作符入符号栈
operStack.push(ch);
}else {//当前操作符大于栈顶优先级
operStack.push(ch);
}
}else {
//为空直接入栈
operStack.push(ch);
}
}else {
//处理多位数时,不能发现是一个数就立即入栈
//不断向后扫描,进行拼接,扫描到运算符入栈
keepNum += ch; //这里为字符串拼接
if(index == expression.length()-1) {
numStack.push(Integer.parseInt(keepNum));
}else {
//判断下一个字符是不是数字
if(operStack.isOper(expression.substring(index+1, index+2).charAt(0))) {
//如果后一位是运算符,入栈
numStack.push(Integer.parseInt(keepNum));
keepNum = "";
}
}
}
//判断是否扫描到字符串最后
index++;
if(index == expression.length()) {
break;
}
}
//扫描完毕,按顺序弹出,并进行运算、
while(true) {
//如果符号栈为空,则计算完毕,数栈中即为结果
if(operStack.isEmpty()) {
break;
}
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.cal(num1, num2, oper);
numStack.push(res);
}
System.out.printf("%s=%d",expression,numStack.pop());
}
}
class ArrayStack2{
private int maxSize; //栈的大小
private int[] stack;
private int top = -1;
//构造器
public ArrayStack2(int maxSize) {
this.maxSize = maxSize;
stack = new int[this.maxSize];
}
//栈满
public boolean isFull() {
return top == maxSize - 1;
}
//栈空
public boolean isEmpty() {
return top == -1;
}
//入栈-push
public void push(int value) {
if(isFull()) {
System.out.println("栈满");
return;
}
top++;
stack[top] = value;
}
//出栈-pop
public int pop() {
if(isEmpty()) {
throw new RuntimeException("栈空");
}
int value = stack[top];
top--;
return value;
}
//遍历栈,从栈顶开始显示
public void list() {
if(isEmpty()) {
System.out.println("栈空");
return;
}
for(int i = top;i>=0;i--) {
System.out.printf("stack[%d]=%d\n",i, stack[i]);
}
}
//扩展功能
//展示栈顶元素
public int peek() {
return stack[top];
}
//返回运算符优先级
public int priority(int oper) {
if(oper == '*'||oper=='/')
return 1;
else if(oper == '+'||oper == '-')
return 0;
else
return -1;
}
//判断是否是运算符
public boolean isOper(char val) {
return val == '+'||val == '-'||val == '*'||val == '/';
}
//计算方法
public int cal(int num1,int num2,int oper) {
int res = 0;
switch(oper) {
case '+':
res = num1 + num2;
break;
case '-':
res = num2 - num1;
break;
case '*':
res = num1 * num2;
break;
case '/':
res = num2/num1;
break;
}
return res;
}
}
This post is licensed under CC BY 4.0 by the author.
