T1(用单链表实现栈的push,top,pop功能)
package Experiment3;
import java.util.Scanner;
public class testMyStack {
public static void main(String[] args) {
System.out.print("输入的元素个数为: ");
Scanner sc = new Scanner(System.in);
myStack stack = new myStack();
int num = sc.nextInt();
System.out.println("输入元素,push");
for (int i = 0 ;i<num;i++)
stack.push(sc.nextInt());
System.out.println("栈顶元素: "+stack.top());
System.out.print("pop()遍历栈:");
while (!stack.isEmpty()){
System.out.print(stack.pop()+ " ");
}
System.out.println();
}
}
class myStack { //创建栈
static ListNode top; //头节点
static int size;
myStack(){
size = 0;
top = new ListNode(-1);
}
public static void push(int data)
{
ListNode newNode = new ListNode(data); //运用头插法可以使得push和pop方法的时间复杂度达到O(1)!! 否侧在pop时都需要遍历链表
newNode.next = top.next;
top.next = newNode;
size++;
}
public static int pop(){
if(isEmpty()) throw new RuntimeException("Stack is empty");
int temp = top.next.data;
top.next = top.next.next;
size--;
return temp;
}
public static int top()
{
if(isEmpty()) throw new RuntimeException("Stack is empty");
return top.next.data;
}
public static boolean isEmpty()
{
if(size!=0) return false;
return true;
}
}
class ListNode{ //创建链表的节点
int data;
ListNode next;
ListNode(){}
ListNode(int data){
this.data = data;
}
}
T2(使用不同的数据结构完成队列)
package Experiment3;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class testMyQueue {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入元素的个数: ");
int num = sc.nextInt();
queue_linkedList queue_linkedList = new queue_linkedList();
queue_array queue_array = new queue_array(num);
queue_circularArray queue_circularArray = new queue_circularArray(num);
Queue<Integer> queue = new LinkedList<>();
System.out.println("请输入你的元素,push");
for (int i = 0;i<num;i++)
{
int temp = sc.nextInt();
queue.offer(temp);
queue_linkedList.push(temp);
queue_array.push(temp);
queue_circularArray.push(temp);
}
System.out.println("访问对头元素");
System.out.println("queue.peek(): "+ queue.peek());
System.out.println("queue_linkedList.peek(): "+ queue_linkedList.peek());
System.out.println("queue_array.peek(): "+queue_array.peek());
System.out.println("queue_circularArray.peek(): "+queue_circularArray.peek());
System.out.println("利用pop()遍历栈");
//-----------------------------------------------------------------------------------
System.out.println("queue的遍历");
while (!queue.isEmpty())
{
System.out.print(queue.poll()+" ");
}
System.out.println();
//--------------------------------------------------------
System.out.println("queue_linkedList的遍历");
while (!queue_linkedList.isEmpty()){
System.out.print(queue_linkedList.pop()+" ");
}
System.out.println();
//--------------------------------------------------------
System.out.println("queue_array的遍历");
while (!queue_array.isEmpty()){
System.out.print(queue_array.pop()+" ");
}
System.out.println();
//--------------------------------------------------------
System.out.println("queue_circularArray");
while (!queue_circularArray.isEmpty()){
System.out.print(queue_circularArray.pop()+" ");
}
System.out.println();
}
}
class queue_linkedList{
ListNode front;
ListNode rear;
int size;
queue_linkedList(){
ListNode newNode = new ListNode();
front = newNode;
size = 0;
rear = front;
}
public void push(int data)
{
ListNode newNode = new ListNode(data);
rear.next = newNode;
rear = rear.next;
size++;
}
public int pop(){
if(isEmpty()) throw new RuntimeException("队列为空");
int temp = front.next.data;
front.next = front.next.next;
size--;
return temp;
}
public int peek(){
if(isEmpty()) throw new RuntimeException("队列为空");
return front.next.data;
}
public boolean isEmpty()
{
if(size==0) return true;
return false;
}
}
class queue_array {
int front;
int rear;
int size;
int[] array;
queue_array(int num)
{
array = new int[num];
front = -1;
rear = 0;
size = 0;
}
public boolean isEmpty()
{
if(size==0) return true;
return false;
}
public boolean isFull()
{
if(size==array.length||rear==array.length) //队列满了或者下标溢出
return true;
return false;
}
public void push(int data)
{
if(isFull()){
System.out.println("队列已满或者数组下标溢出");
System.out.println("数组自动扩容2倍");
array = Arrays.copyOf(array,2*array.length); //java数组的一种扩容方式
}
array[rear++] = data;
size++;
}
public int pop()
{
if(isEmpty()) throw new RuntimeException("队列为空");
size--;
return array[++front];
}
public int peek(){
if(isEmpty()) throw new RuntimeException("队列为空");
return array[front+1];
}
}
class queue_circularArray
{
int front;
int rear;
int[] array;
queue_circularArray(int num) //循环队列
{
front = 0;
rear = 0;
array = new int[num+1];
}
public boolean isEmpty()
{
if(rear == front) return true;
return false;
}
public boolean isFull()
{
if(front==(rear+1)%array.length) return true;
return false;
}
public void push(int data)
{
if(isFull()) throw new RuntimeException("队列已满");
array[(++rear)%array.length] = data;
}
public int pop()
{
if(isEmpty()) throw new RuntimeException("队列为空");
return array[(++front)%array.length];
}
public int peek()
{
if (isEmpty()) throw new RuntimeException("队列为空");
return array[(front+1)%array.length];
}
}
命令框内容:
请输入元素的个数:
4
请输入你的元素,push
1
2
3
4
访问对头元素
queue.peek(): 1
queue_linkedList.peek(): 1
queue_array.peek(): 1
queue_circularArray.peek(): 1
利用pop()遍历栈
queue的遍历
1 2 3 4
queue_linkedList的遍历
1 2 3 4
queue_array的遍历
1 2 3 4
queue_circularArray
1 2 3 4
T3(读文件并判断符号的平衡)
注意需要读完整的文件
package Experiment3;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Stack;
public class test3 {
public static void main(String[] args) throws IOException { //sc.next()中间不能带空格或者换行
//----------------------------------------- 读取文件的全部内容 //sc.nextLine()不能换行
String fileName ="C:\\Users\\10258\\Desktop\\test3.txt";
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line =bufferedReader.readLine();
StringBuffer buffer = new StringBuffer();
boolean flag1 = true;
boolean flag2 = true;
Stack<Character> stack = new Stack<>();
myStack_char stack_char = new myStack_char();
while (line!=null){
buffer.append(line);
line = bufferedReader.readLine();
}
if(!mySolution.isValid(buffer,stack)){
System.out.println("stack: not balance");
}else{
System.out.println("stack: balance");
}
if(!stack_char.isValid(buffer,stack_char)){
System.out.println("myStack: not balance");
}else{
System.out.println("myStack: balance ");
}
bufferedReader.close();
fileReader.close();
}
//----------------------------------------
}
class myStack_char { //创建栈
ListNode_char top; //头节点
int size;
myStack_char(){
size = 0;
top = new ListNode_char();
}
public void push(char data)
{
ListNode_char newNode = new ListNode_char(data); //运用头插法可以使得push和pop方法的时间复杂度达到O(1)!! 否侧在pop时都需要遍历链表
newNode.next = top.next;
top.next = newNode;
size++;
}
public char pop(){
if(isEmpty()) throw new RuntimeException("Stack is empty");
char temp = top.next.data;
top.next = top.next.next;
size--;
return temp;
}
public char top()
{
if(isEmpty()) throw new RuntimeException("Stack is empty");
return top.next.data;
}
public boolean isEmpty()
{
if(size!=0) return false;
return true;
}
public boolean isValid(StringBuffer s,myStack_char stack) {
for(int i = 0;i < s.length();i++)
{
if(s.charAt(i)=='('||s.charAt(i)=='['||s.charAt(i)=='{')
{
stack.push(s.charAt(i));
}else if(s.charAt(i)=='/'&&s.charAt(++i)=='*'){
stack.push('/');
stack.push('*');
}else if(Character.isLetter(s.charAt(i))) continue;
else if(s.charAt(i)==')'&&stack.pop()!='(') return false;
else if(s.charAt(i)==']'&&stack.pop()!='[') return false;
else if(s.charAt(i)=='}'&&stack.pop()!='{') return false;
else if(s.charAt(i)=='*'&&s.charAt(++i)=='/'){
if(stack.pop()!='*') return false;
if(stack.pop()!='/') return false;
}
}
return stack.isEmpty();
}
}
class ListNode_char{ //创建链表的节点
char data;
ListNode_char next;
ListNode_char(){}
ListNode_char(char data){
this.data = data;
}
}
class mySolution {
public static boolean isValid(StringBuffer s,Stack<Character> stack) {
for(int i = 0;i < s.length();i++)
{
if(s.charAt(i)=='('||s.charAt(i)=='['||s.charAt(i)=='{')
{
stack.push(s.charAt(i));
}else if(s.charAt(i)=='/'&&s.charAt(++i)=='*'){
stack.push('/');
stack.push('*');
}else if(Character.isLetter(s.charAt(i))) continue;
else if(s.charAt(i)==')'&&stack.pop()!='(') return false;
else if(s.charAt(i)==']'&&stack.pop()!='[') return false;
else if(s.charAt(i)=='}'&&stack.pop()!='{') return false;
else if(s.charAt(i)=='*'&&s.charAt(++i)=='/'){
if(stack.pop()!='*') return false;
if(stack.pop()!='/') return false;
}
}
return stack.isEmpty();
}
}
测试用例:
注意:文件路径需要自己设置,在记事本中更改后需要Ctrl+s保存再测试
代码还是不能直接测试,代码中含大量的自己设置的字符串符号和char里自己设置的符号以及注释//等,对只含字母和符号有较好效果
T5(中缀表达式转后缀表达式,利用后缀表达式计算)
package Experiment3;
import java.util.Scanner;
import java.util.Stack;
public class test5 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String infix = sc.nextLine();
System.out.println(infix);
String[] strArray = infix.split(" ");
String postfix = Solution.transform(strArray);
System.out.println("转成后缀表达式: "+postfix);
System.out.println("答案: "+Solution.evalRPN(postfix.split(" ")));
}
}
class Solution {
public static int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for(String s : tokens)
{
if(s.equals("+"))
{
stack.push(stack.pop()+stack.pop());
}else if(s.equals("-")){
stack.push(-stack.pop()+stack.pop());
}else if(s.equals("*"))
{
stack.push(stack.pop()*stack.pop());
}else if(s.equals("/")){
int a = stack.pop();
int b = stack.pop();
stack.push(b/a);
}else{
stack.push(Integer.parseInt(s));
}
}
return stack.pop();
}
public static String transform(String[] infix) //较复杂,需要注意判断的先后顺序
{
Stack<String> stack1 = new Stack<>();
Stack<String> stack2 = new Stack<>();
for(String a: infix)
{
if(a.equals("+")||a.equals("-")||a.equals("*")||a.equals("/")||a.equals("(")||a.equals(")")){
if(a.equals(")")) {
while (!stack1.peek().equals("(")){
stack2.push(stack1.pop());
}
stack1.pop();
}
else if(stack1.isEmpty()||stack1.peek().equals("(")||a.equals("(")){ //空栈也直接压入
stack1.push(a);
}
else if((stack1.peek().equals("+")||stack1.peek().equals("-"))&&(a.equals("*")||a.equals("/"))){
stack1.push(a);
}
else{
stack2.push(stack1.pop());
stack1.push(a);
}
}else{
stack2.push(a);
}
}
while (!stack1.isEmpty()){
stack2.push(stack1.pop());
}
String result = "";
while (!stack2.isEmpty()){
result = stack2.pop()+" "+result;
}
return result;
}
}
一个中缀转后缀的例子:
测试用例:
要求输入的公式各种数字和符号之间用空格隔开
仅做了两个测试用例,无法保证这个一定准确