栈
先进来的最后出去,后进来的先出去。
放元素: 压栈 push
取元素: 出栈/弹栈。 pop
操作是针对 栈顶。栈底不允许做。
压栈 和 弹栈
可以类比 为 手枪 上子弹,子弹发射。
栈的实现
任何表都可以 用来实现 栈。
主要的两种方式: 链表 和 数组。
链表实现栈
动态栈: 使用 链表 实现 栈
特点: 元素 和 元素 间 ,物理上不连续,但是功能受限。
只能在 栈顶 进行 插入 和 删除, 栈尾 不允许 操作。
数组实现栈
静态栈: 使用 数组 实现 栈
栈的应用场景
子程序的调用
处理递归
表达式转换
二叉树遍历
图形的深度优先遍历DFS(depth first)
栈入门
/*
*/
public class ArrayStack {
// 栈的大小
private int maxStack;
private int[] stack;
// 表示栈顶所在的位置,默认情况下没有数据,使用-1
private int top = -1;
public ArrayStack(int maxStack){
this.maxStack = maxStack;
}
/*
1.压栈
2.弹栈
3.判断是否空栈
4.当前栈中是否满栈
*/
// 当前栈中是否满栈
public boolean isFull(){
return this.top == this.maxStack - 1;
}
// 是否空栈
public boolean isEmpty(){
return this.top == -1;
}
// 压栈:
public void push(int val){
// 判断是否满栈
if(isFull()){
throw new RuntimeException("此栈已满!");
}
top ++;
stack[top] = val;
}
// 弹栈
public int pop(){
//如果栈是空的
if(isEmpty()){
throw new RuntimeException("空栈,未找到数据!");
}
int value = stack[top];
top --;
return value;
}
// 查看栈中所有元素
public void list(){
//判断是否空栈
if(isEmpty()){
throw new RuntimeException("空栈,未找到数据!");
}
for (int i = 0; i < stack.length; i ++){
System.out.printf("stack[%d] = %d\n", i,stack[i]);
}
}
}
使用栈 实现回文数
/*
*/
public class ArrayStack {
private int maxStack;// 栈的大小
private int[] stack;
private int top = -1;// 表示栈顶所在的位置,默认情况下没有数据,使用-1
public ArrayStack(int maxStack){
this.maxStack = maxStack;
stack = new int[maxStack];
}
/*
1.压栈
2.弹栈
3.判断是否空栈
4.当前栈中是否满栈
*/
// 当前栈中是否满栈
public boolean isFull(){
return this.top == this.maxStack - 1;
}
// 是否空栈
public boolean isEmpty(){
return this.top == -1;
}
// 压栈:
public void push(int val){
// 判断是否满栈
if(isFull()){
throw new RuntimeException("此栈已满!");
}
top ++;
stack[top] = val;
}
// 弹栈
public int pop(){
//如果栈是空的
if(isEmpty()){
throw new RuntimeException("空栈,未找到数据!");
}
int value = stack[top];
top --;
return value;
}
// 查看栈中所有元素
public void list(){
//判断是否空栈
if(isEmpty()){
throw new RuntimeException("空栈,未找到数据!");
}
for (int i = 0; i < stack.length; i ++){
System.out.printf("stack[%d] = %d\n", i,stack[i]);
}
}
// 栈中元素存在的个数
public int length(){
return this.top + 1;
}
}
public class TestApp {
public static void main(String[] args) {
/*
回文数据
回文: aba
需求:通过 之前创建的栈 来判断一个数字是否是回文数据
*/
System.out.println(detecation("hello"));
System.out.println(detecation("aba"));
System.out.println(detecation("ab123123123a"));
}
public static boolean detecation(String val){
// 初始化栈对象
// 获取字符串长度
int length = val.length();
ArrayStack arrayStack = new ArrayStack(length);
// 把字符串的数据 一个一个 压栈到数组中
for(int i = 0; i < length; i++){
arrayStack.push(val.charAt(i));
}
String newVal = "";
int length1 = arrayStack.length();
for (int i = 0; i < length1; i++){
// 是否是一个空栈
if (!arrayStack.isEmpty()){
char pop = (char)arrayStack.pop();
newVal += pop;
}
}
if (val.equals(newVal)){
return true;
} else {
return false;
}
}
}
使用 栈 完成 字符串 计算
步骤:
- 循环遍历出 每一个元素
- 如果是数字,压入 数字栈。如果是 符号, 压入 符号栈。
- 如果符号:
如果符号栈为空,则符号立即入栈。
如果符号栈不为空,先去对比栈中 符号的优先级。如果优先级小于等于 栈中的符号,应该需要先计算 原来 数字栈中的数据,将得到的结果再次入栈。入栈之后,在把符号入 符号栈。如果优先级 大于 原来符号栈中符号,直接将符号入栈即可。
最终获取一个表达式结果。
stack 的源代码
/*
*/
public class ArrayStack {
private int maxStack;// 栈的大小
private int[] stack;
private int top = -1;// 表示栈顶所在的位置,默认情况下没有数据,使用-1
// constructor
public ArrayStack(int maxStack){
this.maxStack = maxStack;
this.stack = new int[this.maxStack];
}
// 当前栈中是否满栈
public boolean isFull(){
return this.top == this.maxStack - 1;
}
// 是否空栈
public boolean isEmpty(){
return this.top == -1;
}
// 压栈
public void push(int val){
// 判断是否满栈
if(isFull()){
throw new RuntimeException("此栈已满!");
}
top ++;
stack[top] = val;
}
// 弹栈
public int pop(){
//如果栈是空的
if(isEmpty()){
throw new RuntimeException("空栈,未找到数据!");
}
int value = stack[top];
top --;
return value;
}
// 查看栈中所有元素
public void list(){
//判断是否空栈
if(isEmpty()){
throw new RuntimeException("空栈,未找到数据!");
}
for (int i = 0; i < stack.length; i ++){
System.out.printf("stack[%d] = %d\n", i,stack[i]);
}
}
// 栈中元素存在的个数
public int length(){
return this.top + 1;
}
// 判断是否是一个运算符
public boolean isOper(char v){
return v == '+' || v == '-' || v == '*' || v == '/';
}
// 判断运算符优先级 使用数字表示优先级大小,数字越大的,优先级也越大
public int priority(int oper){
if (oper == '*' || oper == '/'){
return 1;
} else if (oper == '+' || oper == '-'){
return 0;
}
// 其他运算符,不作为计算
return -1;
}
// 获取栈的容量
public int stackLength(){
return this.stack.length;
}
// 获取栈顶数据
public int peek(){
return this.stack[top];
}
// 计算两个数进行运算后的结果
public int calculate(int num1, int num2, int oper){
// 2 + 3
// num1: 3; num2 : 2
int result = 0;
switch (oper){
case '+':
result = num1 + num2;
break;
case '-':
result = num2 - num1;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num2 / num1;
break;
default:
break;
}
return result;
}
}
使用stack 对 str进行 计算
/*
*/
public class ArrayStack {
private int maxStack;// 栈的大小
private int[] stack;
private int top = -1;// 表示栈顶所在的位置,默认情况下没有数据,使用-1
// constructor
public ArrayStack(int maxStack){
this.maxStack = maxStack;
this.stack = new int[this.maxStack];
}
// 当前栈中是否满栈
public boolean isFull(){
return this.top == this.maxStack - 1;
}
// 是否空栈
public boolean isEmpty(){
return this.top == -1;
}
// 压栈
public void push(int val){
// 判断是否满栈
if(isFull()){
throw new RuntimeException("此栈已满!");
}
top ++;
stack[top] = val;
}
// 弹栈
public int pop(){
//如果栈是空的
if(isEmpty()){
throw new RuntimeException("空栈,未找到数据!");
}
int value = stack[top];
top --;
return value;
}
// 查看栈中所有元素
public void list(){
//判断是否空栈
if(isEmpty()){
throw new RuntimeException("空栈,未找到数据!");
}
for (int i = 0; i < stack.length; i ++){
System.out.printf("stack[%d] = %d\n", i,stack[i]);
}
}
// 栈中元素存在的个数
public int length(){
return this.top + 1;
}
// 判断是否是一个运算符
public boolean isOper(char v){
return v == '+' || v == '-' || v == '*' || v == '/';
}
// 判断运算符优先级 使用数字表示优先级大小,数字越大的,优先级也越大
public int priority(int oper){
if (oper == '*' || oper == '/'){
return 1;
} else if (oper == '+' || oper == '-'){
return 0;
}
// 其他运算符,不作为计算
return -1;
}
// 获取栈的容量
public int stackLength(){
return this.stack.length;
}
// 获取栈顶数据
public int peek(){
return this.stack[top];
}
// 计算两个数进行运算后的结果
public int calculate(int num1, int num2, int oper){
// 2 + 3
// num1: 3; num2 : 2
int result = 0;
switch (oper){
case '+':
result = num1 + num2;
break;
case '-':
result = num2 - num1;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num2 / num1;
break;
default:
break;
}
return result;
}
}