数据结构与算法(Java)之栈
Posted 达少Rising
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法(Java)之栈相关的知识,希望对你有一定的参考价值。
数组实现栈
package com.weeks.stack;
import java.util.Scanner;
/**
* @author 达少
* @version 1.0
*/
public class ArrayStackDemo {
public static void main(String[] args) {
//创建栈
ArrayStack arrayStack = new ArrayStack(4);
//创建输入扫描器,并接收用户输入
Scanner scanner = new Scanner(System.in);
char key = ' ';
//控制while循环
boolean loop = true;
//测试各个方法
while(loop){
System.out.println("\\n栈操作方法菜单:\\n" +
"1 push 数据入栈\\n" +
"2 pop 数据出栈\\n" +
"3 list 显示栈中数据\\n" +
"4 exit 退出程序\\n");
System.out.print("请输入你的选择:");
key = scanner.next().charAt(0);
switch (key){
case '1':
System.out.print("请输入一个整数:");
int value = scanner.nextInt();
arrayStack.push(value);
break;
case '2':
try {
int res = arrayStack.pop();
System.out.printf("本次出栈的数据为:%d\\n", res);
} catch (Exception e) {
System.out.println(e);
}
break;
case '3':
arrayStack.list();
break;
case '4':
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("退出程序~~~");
}
}
class ArrayStack{
private int maxSize;//表示栈的容量
private int top = -1;//表示栈顶,默认值为-1
private int[] stack;//使用数组模拟栈
//在有参构造方法中初始化栈
public ArrayStack(int maxSize){
this.maxSize = maxSize;
this.stack = new int[this.maxSize];
}
//满栈判断
public boolean isFull(){
return top == maxSize - 1;
}
//空栈判断
public boolean isEmpty(){
return top == -1;
}
//数据入栈
public void push(int value){
//判断是否满栈
if(isFull()){
System.out.println("已满栈,无法入栈!!!");
return;
}
//入栈
stack[++top] = value;
}
//数据出栈
public int pop(){
//判断是否栈空
if(isEmpty()){
throw new RuntimeException("栈已空,没有数据可以出栈!!!");
}
//出栈过程
//1.将出栈数据赋值给临时变量
int res = stack[top];
//2.top下移
top--;
//3.将出栈数据返回
return res;
}
//遍历栈
public void list(){
//判断栈是否为空
if(isEmpty()){
System.out.println("栈已空,没有数据可遍历!!!");
return;
}
//遍历
for(int i = top; i > -1; i--){
System.out.printf("arr[%d]=%d\\n", i, stack[i]);
}
}
}
单链表实现栈
package com.weeks.stack;
import java.util.Scanner;
/**
* @author 达少
* @version 1.0
* 使用单链表的头插法实现栈
*/
public class LinkedListStackDemo {
public static void main(String[] args) {
//创建栈
LinkedListStack stack = new LinkedListStack();
//创建输入扫描器,并接收用户输入
Scanner scanner = new Scanner(System.in);
char key = ' ';
//控制while循环
boolean loop = true;
//测试各个方法
while(loop){
System.out.println("\\n栈操作方法菜单:\\n" +
"1 push 数据入栈\\n" +
"2 pop 数据出栈\\n" +
"3 list 显示栈中数据\\n" +
"4 exit 退出程序\\n");
System.out.print("请输入你的选择:");
key = scanner.next().charAt(0);
switch (key){
case '1':
System.out.print("请输入一个整数:");
int value = scanner.nextInt();
stack.push(value);
break;
case '2':
try {
int res = stack.pop();
System.out.printf("本次出栈的数据为:%d\\n", res);
} catch (Exception e) {
System.out.println(e);
}
break;
case '3':
stack.list();
break;
case '4':
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("退出程序~~~");
}
}
class LinkedListStack{
//头节点不存储具体的数据
private Node head = new Node(0);
//空栈判断
public boolean isEmpty(){
return head.getNext() == null;
}
//入栈使用头插法插入链表
public void push(int value){
//创建入栈节点
Node node = new Node(value);
//插入到链表的头节点下一个位置
node.setNext(head.getNext());
head.setNext(node);
}
//出栈,因为使用头插法入栈,所以要从链表的头节点的下一个位置开始出栈
public int pop(){
//判断是否空栈
if (isEmpty()){
throw new RuntimeException("栈已空,没有数据可以出栈!!!");
}
//出栈
//1.将要出栈的节点数据赋值给临时变量
int res = head.getNext().getData();
//2.将出栈的节点从链表中删除
head.setNext(head.getNext().getNext());
return res;
}
//遍历栈,从头节点的下一个位置开始输出链表数据
public void list(){
//判断是否空栈
if(isEmpty()){
System.out.println("栈已空,不可遍历!!!");
return;
}
//头节点不能动,需要定义辅助变量遍历栈
Node cur = head.getNext();
while(cur != null){
System.out.println(cur);
//下移cur
cur = cur.getNext();
}
}
}
class Node{
private int data;
private Node next;
public Node(int data){
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public String toString() {
return "Node = " + data;
}
}
栈实现综合计算器
中缀表达式
package com.weeks.stack.calculator;
/**
* @author 达少
* @version 1.0
* 使用栈实现综合计算(中缀表达式的计算)
*/
public class CalculatorDemo {
public static void main(String[] args) {
//创建数栈
LinkedListStack numStack = new LinkedListStack();
//创建符号栈
LinkedListStack operatorStack = new LinkedListStack();
//计算表达式
String expression = "700+2*6-2";
//创建辅助变量
int index = 0;//帮助扫描计算表达式
char curChar = ' ';
String keepNum = "";//定义变量拼接数字符号
//扫描计算表达式,入栈规则:
//1.当所扫描的字符是数字,可以直接压入数栈中
//2.当所扫描的字符是操作符,有三种情况:
// 1)当符号栈为空栈时,当前操作符直接压入符号栈中
// 2)当前操作符的优先级小于或等栈顶的操作符时,将栈顶操作符弹出,
// 并在数栈中弹出两个数,进行运算,将运算的结果压入数栈中,并将当前操作符压入符号栈
// 3)当前操作符的优先级大于栈顶的操作符时,当前操作符直接入栈
while(index < expression.length()){
//将当前index位置的字符取出
curChar = expression.substring(index, index+1).charAt(0);
//判断当前的字符是否为操作符
if(operatorStack.isOperator(curChar)){
//当符号栈为空栈时,当前操作符直接压入符号栈中
if (operatorStack.isEmpty()){
operatorStack.push(curChar);
}else if(operatorStack.priority(curChar) <= operatorStack.priority((char) operatorStack.getTop())){
//当前操作符的优先级小于或等栈顶的操作符时,将栈顶操作符弹出,
//并在数栈中弹出两个数,进行运算,将运算的结果压入数栈中,并将当前操作符压入符号栈
char opr = (char) operatorStack.pop();
int num1 = 0;
int num2 = 0;
try {
num1 = numStack.pop();
num2 = numStack.pop();
} catch (Exception e) {
System.out.println(e.getMessage());
}
int res = numStack.calculate(num1, num2, opr);
numStack.push(res);
operatorStack.push(curChar);
}else{
operatorStack.push(curChar);
}
}else{//当前字符为数字
//当前的字符是数字也分两种情况:
//1.字符串已经到末尾了
//2.字符串还没到末尾,下一个字符也是数字
//numStack.push(curChar - 48);//ascii码表
if(index == expression.length() - 1){
//1.字符串已经到末尾了,当前字符直接入栈
numStack.push(curChar - 48);//ascii码表
}else{
//当前数字符号与keepNum拼接
keepNum += curChar;
//判断下一个字符的类型
char nextChar = expression.substring(index+1, index+2).charAt(0);
if(operatorStack.isOperator(nextChar)){
//如果下一个是符号类型将当前的字符串数字直接入栈
numStack.push(Integer.parseInt(keepNum));
//入栈后要清空keepNum
keepNum = "";
}
}
}
index++;//index自增
}
while(true){
if(operatorStack.isEmpty()){
break;
}
char opr = (char) operatorStack.pop();
int num1 = numStack.pop();
int num2 = numStack.pop();
int res = numStack.calculate(num1, num2, opr);
numStack.push(res);
}
System.out.printf("计算的结果%s = %d", expression, numStack.pop());
}
}
class LinkedListStack{
//头节点不存储具体的数据
private Node head = new Node(-1);
//空栈判断
public boolean isEmpty(){
return head.getNext() == null;
}
//入栈使用头插法插入链表
public void push(int value){
//创建入栈节点
Node node = new Node(value);
//插入到链表的头节点下一个位置
node.setNext(head.getNext());
head.setNext(node);
}
//出栈,因为使用头插法入栈,所以要从链表的头节点的下一个位置开始出栈
public int pop(){
//判断是否空栈
if (isEmpty()){
throw new RuntimeException("栈已空,没有数据可以出栈!!!");
}
//出栈
//1.将要出栈的节点数据赋值给临时变量
int res = head.getNext().getData();
//2.将出栈的节点从链表中删除
head.setNext(head.getNext().getNext());
return res;
}
//遍历栈,从头节点的下一个位置开始输出链表数据
public void list(){
//判断是否空栈
if(isEmpty()){
System.out.println("栈已空,不可遍历!!!");
return;
}
//头节点不能动,需要定义辅助变量遍历栈
Node cur = head.getNext();
while(cur != null){
System.out.以上是关于数据结构与算法(Java)之栈的主要内容,如果未能解决你的问题,请参考以下文章