Java数据结构与算法4 栈

栈(stack) 是一种先入后出的线性结构
应用:子程序的调用/递归调用/表达式求值(中缀表达式转后缀表达式)/二叉树遍历/图的DFS

使用数组来模拟栈

初始化:top = -1
入栈:top++,stack[top] = data
出栈: int value = stack[top], top–,return value

package com.like.java.data_structure.stack;

// 表示栈结构
public 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;
	}
	
	public void push(int val)
	{
		if(isFull())
		{
			System.err.println("Full");
			return;
		}
		stack[++top] = val;
	}
	
	public int pop()
	{
		if(isEmpty())
		{
			throw new RuntimeException("Empty Stack,No data");
		}
		return stack[top--];
	}
	
	public void show()
	{
		if(isEmpty())
		{
			throw new RuntimeException("Empty Stack,No data");
		}
		for(int i=top;i>=0;i--)
		{
			System.out.println("stack["+i+"]="+stack[i]);
		}
	}
}

使用链表来模拟栈

package com.like.java.data_structure.stack;
import com.like.java.data_structure.linkedList.Boy;

public class LinkedStack {
	private Boy bottom = new Boy(-1);
	private Boy top = bottom;
	
	public boolean isEmpty()
	{
		return bottom == top;
	}
	
	public void push(Boy boy)
	{
		boy.next = top;
		top = boy;
	}
	
	public Boy pop()
	{
		if(isEmpty())
		{
			System.err.println("Empty Stack");
			return null;
		}
		
		Boy curBoy = top;
		top = top.next;
		return curBoy;
	}
	
	public void show()
	{
		Boy temp = top;
		while(temp != bottom)
		{
			System.out.println(temp);
			temp = temp.next;
		}
	}
}

使用栈实现综合计算器

对于一个中缀表达式形如722-5+1+5+3-4,使用栈来计算综合的结果
思想:1. 通过一个index值来遍历表达式
2. 如果是一个数字,直接加入到数栈中
3. 如果是运算符,分为两种情况
- 3.1 若符号栈为空,直接入栈
- 3.2 若符号栈不为空,比较当前操作符和栈中操作符进行比较
当前运算符小或等于栈中,就从数栈中pop出两个数,从符号栈中pop出一个,运算出结果入数栈,然后将当前操作符如符号栈(Note 后面弹出的数 操作符 前面弹出的数)
当前运算符优先级大于栈中的操作符,直接入符号栈
4. 当表达式扫描完毕后,就顺序地从数栈和符号栈中pop出相应的数和符号栈就行运算,最后数栈中只有一个数值即运算结果

package com.like.java.data_structure.stack;

// 用于综合计算器
public 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;
	}
	
	public void push(int val)
	{
		if(isFull())
		{
			System.err.println("Full");
			return;
		}
		stack[++top] = val;
	}
	
	public int pop()
	{
		if(isEmpty())
		{
			throw new RuntimeException("Empty Stack,No data");
		}
		return stack[top--];
	}
	
	public void show()
	{
		if(isEmpty())
		{
			throw new RuntimeException("Empty Stack,No data");
		}
		for(int i=top;i>=0;i--)
		{
			System.out.println("stack["+i+"]="+stack[i]);
		}
	}
	
	// 增加优先级判断功能
	// 优先级使用数字表示,数字越大,优先级越大
	public int priority(int oper)
	{
		if(oper == '*' || oper == '/')
		{
			return 1;
		}
		else if(oper == '+' || oper == '-')
		{
			return 0;
		}else {
			return -1;
		}
	}

	// 判断是不是运算符
	public boolean isOper(int oper)
	{
		return oper == '+' || oper == '-' || oper == '*' || oper == '/';
	}
	
	// 计算方法
	public int calc(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;
	}

	// peek
	public int peek()
	{
		return stack[top];
	}
}

package com.like.java.data_structure.stack;

public class Calculator {
	public static void main(String[] args) {
		String expression = "3+2*6-2*9";
		
		ArrayStack2 numStack2 = new ArrayStack2(10);
		ArrayStack2 operStack2 = new ArrayStack2(10);
		
		int index = 0; // 扫描
		int num1 = 0,num2 = 0;
		int res = 0;
		int oper = 0;
		char ch = ' ';
		
		// 扫描入栈
		while(index < expression.length())
		{
			ch = expression.charAt(index++);
			if(operStack2.isOper(ch))
			{
				if(!operStack2.isEmpty())
				{
					if(operStack2.priority(ch) <= operStack2.priority(operStack2.peek()))
					{
						num1 = numStack2.pop();
						num2 = numStack2.pop();
						oper = operStack2.pop();
						res = operStack2.calc(num1, num2, oper);
						numStack2.push(res);
						// 当前操作符入符号栈
						operStack2.push(ch);
					}else {
						operStack2.push(ch);
					}
				}
				else {
					operStack2.push(ch);
				}
			}else {
				numStack2.push(ch-48);
			}
		}
		
		// 扫描完毕运算到符号栈为空
		while(!operStack2.isEmpty())
		{
			num1 = numStack2.pop();
			num2 = numStack2.pop();
			oper = operStack2.pop();
			res = operStack2.calc(num1, num2, oper);
			numStack2.push(res);
		}
		
		System.out.printf("%s=%d",expression,numStack2.pop());
	}
}

Java.util.Stack示例

package com.like.java.data_structure.stack;

import java.util.Stack;

public class StackTester {
	public static void main(String[] args) {
		Stack<String> stack = new Stack<String>();
		// 入栈
		stack.setSize(3);
		stack.add("Jack");
		stack.add("Tom");
		stack.add("Alice");
		
		String isPush = stack.push("Like");
		boolean isAdd = stack.add("Smith");
		
		System.out.println(isPush);
		System.out.println(isAdd);
		// 出栈
	    System.out.println(stack.pop());
	
		// 查看栈顶元素
		System.out.println(stack.peek());
		
		//查看栈大小
		System.out.println(stack.size());
		
	}
}
发布了80 篇原创文章 · 获赞 332 · 访问量 70万+

猜你喜欢

转载自blog.csdn.net/qq_40527086/article/details/104341873