【Java数据结构与算法】 基础篇(3):栈、四则表达式运算、中缀表达式转后缀表达式、递归

10 篇文章 0 订阅
9 篇文章 0 订阅

大家好,我是皮皮猫吖!

每文一言:他们试图埋掉你,但你要知道你是种子!

本篇文章:

主要是关于java数据结构与算法的一些基本知识:栈的学习、栈实现四则运算、栈实现带符号的四则运算、中缀表达式转后缀表达式、递归解决迷宫问题、回溯解决8皇后问题。

栈应用一:栈实现带符号的四则运算

栈应用二:栈实现中缀表达式转后缀表达式

递归应用一:递归实现迷宫问题

递归应用二:8皇后问题

正文如下:

1、栈

1)栈的介绍:

① 栈的英文为(stack)

② 栈是一个先入后出(FILO-First In Last Out)的有序列表。

③ 栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。

④ 根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除

⑤ 图解出栈(Pop())和入栈(push()):

  • 入栈操作

在这里插入图片描述

  • 出栈操作
    在这里插入图片描述
2)栈的应用场景

① 子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。

② 处理递归调用:和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。

★③ 表达式的转换[中缀表达式转后缀表达式]与求值(实际解决)。

★④ 二叉树的遍历。

★⑤ 图形的深度优先(depth一first)搜索法。

3)数组模拟栈的思路图:

在这里插入图片描述

4)数组模拟栈的代码
package com.data.structure.study4.stack;

/**
 * @author imppm
 * @create 2021-03-08-20:42
 */
public class StackDemo1 {
    public static void main(String[] args) {
     Stack1 stack1 = new Stack1();

     stack1.push(1);
     stack1.push(2);
     stack1.push(3);
     stack1.push(4);
     stack1.push(5);

     stack1.list();

    }
}


class Stack1{
    //栈存储数据的最大值
    private int MAXSIZE = 10;

    //数组模拟栈
    private int[] stack;

    //栈顶指针:初始化为-1
    private int top = -1;

    //初始化栈
    private void initStack(int size){
        stack = new int[size];
    }

    //入栈
    public void push(int data){
        if(stack == null){
            initStack(MAXSIZE);
        }

        if(isFull()){
            System.out.println("栈已满,添加数据失败!");
            return;
        }
        stack[++top] = data;
        System.out.printf("数据%d入栈成功!\n",data);
    }

    //出栈
    public int pop(){
        if(isEmpty()){
            throw new RuntimeException("栈中没有数据,请先添加数据!");
        }
        int data = stack[top--];
        System.out.printf("数据%d出栈成功!\n",data);
        return data;
    }

    //遍历栈:从栈顶到栈底开始遍历 
    public void list(){
        //current=top
        int current = top;

        while (current!=-1){
            System.out.println("栈中的数据:"+stack[current--]);
        }
    }

    //判断栈是否为空
    private boolean isEmpty(){
        return top == -1;
    }

    //判断栈是否已满
    private boolean isFull(){
        return MAXSIZE-1 == top;
    }



}


5)链表模拟栈的代码
package com.data.structure.study4.stack;

import java.util.Stack;

/**
 * @author imppm
 * @create 2021-03-09-15:29
 */
public class LinkedListStackDemo1 {
    public static void main(String[] args) {
        LinkedListStack stack = new LinkedListStack();

        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.push(5);
        stack.push(6);

        stack.list();
    }
}

class LinkedListStack{
    //栈指针:指向第一个数据的前一个地址
    private Stack2 top = null;

    //判断当前栈是否为空
    public boolean isEmpty(){
        return top == null;
    }

    //入栈
    public void push(int data){
        //创建节点
        Stack2 stack2 = new Stack2(data, null);

        //创建的节点指向栈顶指针指向的节点
        stack2.setNext(top);

        //栈顶指针指向新创建的节点
        top = stack2;
        System.out.printf("数据%d入栈成功!\n",data);
    }

    //出栈
    public Stack2 pop(){
        if(isEmpty()){
            throw new RuntimeException("当前栈为空,没有数据出栈!");
        }

        //获取到当前栈顶节点
        Stack2 stack2 = top;

        //数据出栈
        //top指针指向栈顶元素
        top = top.getNext();

        //
        System.out.println("栈数据为"+stack2);
        return stack2;
    }


    //遍历栈
    public void list(){
        Stack2 current = top;
        while (current!=null){
            System.out.println("栈中的数据为"+current);
            current = current.getNext();
        }
    }
}

class Stack2{
    private int data;
    private Stack2 next;

    public Stack2() {
    }

    public Stack2(int data, Stack2 next) {
        this.data = data;
        this.next = next;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public Stack2 getNext() {
        return next;
    }

    public void setNext(Stack2 next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "Stack2{" +
                "data=" + data +
                '}';
    }
}

6)栈的应用1: 简单四则表达式的计算:7 * 2 * 2 - 5 + 1 - 5 + 3 - 4 = 18

应用篇(1):栈实现四则表达式运算、栈实现带符号的四则表达式计算

7)栈的应用2:带小括号四则表达式的计算:(1 + 2) - 3 * 4 + 2 * (1+2) = -3

应用篇(1):栈实现四则表达式运算、栈实现带符号的四则表达式计算

应用篇(2):中缀表达式转后缀表达式、带小括号四则表达式运算

2、前缀、中缀、后缀表达式(逆波兰表达式)

应用篇(2):中缀表达式转后缀表达式、带小括号四则表达式运算

3、递归

1)递归是什么?

简单的说: 递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。

2)递归的调用机制:
① 打印问题:

在这里插入图片描述

3)递归的相关应用,能够解决什么问题:

① 各种数学问题如: 8皇后问题 , 汉诺塔, 阶乘问题, 迷宫问题, 球和篮子的问题

② 各种算法中也会使用到递归,比如快排,归并排序,二分查找,分治算法等。

③ 将用栈解决的问题–>递归代码比较简洁

4)递归需要遵守的规则:

① 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)。

② 方法的局部变量是独立的,不会相互影响, 比如n变量。

③ 如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据。

递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError,死龟了:)。

⑤ 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。

5)递归:迷宫问题

应用篇(3):递归解决迷宫问题,回溯解决八皇后问题

6)递归:八皇后问题(回溯算法)

应用篇(3):递归解决迷宫问题,回溯解决八皇后问题


希望本篇文章对大家有所帮助,后续会继续分享java数据结构与算法相关学习知识…

如果文章内容有错误的地方,请在留言处留下你的见解,方便大家共同学习。谢谢!

如有侵权或其他任何问题请联系:QQ1370922071,本文主要用于学习交流,转载请声明!

作者:皮皮猫吖


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值