• 数据结构与算法系列六(栈)


    1.引子

    1.1.为什么要学习数据结构与算法?

    有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀!

    有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗?

    于是问题来了:为什么还要学习数据结构与算法呢?

    #理由一:
        面试的时候,千万不要被数据结构与算法拖了后腿
    #理由二:
        你真的愿意做一辈子CRUD Boy吗
    #理由三:
        不想写出开源框架,中间件的工程师,不是好厨子

    1.2.如何系统化学习数据结构与算法?

    我想好了,还是需要学习数据结构与算法。但是我有两个困惑:

    1.如何着手学习呢?

    2.有哪些内容要学习呢?

    学习方法推荐:

    #学习方法
    1.从基础开始,系统化学习
    2.多动手,每一种数据结构与算法,都自己用代码实现出来
    3.思路更重要:理解实现思想,不要背代码
    4.与日常开发结合,对应应用场景

    学习内容推荐:

    数据结构与算法内容比较多,我们本着实用原则,学习经典的、常用的数据结构、与常用算法

    #学习内容:
    1.数据结构的定义
    2.算法的定义
    3.复杂度分析
    4.常用数据结构
        数组、链表、栈、队列
        散列表、二叉树、堆
        跳表、图
    5.常用算法
        递归、排序、二分查找
        搜索、哈希、贪心、分治
        动态规划、字符串匹配

    2.考考你

    你还记得在数组那一篇中,我们说过基于线性表的数据结构有哪些吗?它们是:数组、链表、栈、队列。

    前面我们详细了解了数组和链表,数组和链表是很多数据结构和算法的基础数据结构。比如我们今天要学习的栈,就可以通过数组实现:顺序栈;也可以通过链表实现:链式栈

    那么问题来了:栈到底是什么样的数据结构呢?

    #考考你:
    1.你能用自己的话描述栈吗?
    2.你知道栈都有哪些常见的应用场景吗?

    3.案例

    3.1.栈的定义

    栈是一种基于线性表的特殊数据结构,说它特殊,是因为栈是操作受限的。栈只允许在栈顶一端插入数据和删除数据。满足后进先出的特点。

    3.2.代码实现

    顺序栈代码:

    package com.anan.struct.linetable;
    
    /**
     * 顺序栈:基于数组实现
     * @param <E>
     */
    public class ArrayStack<E> {
    
        private Object[] items;
        private int count;// 计数器(统计栈内元素个数)
        private int n;// 栈大小
    
        public ArrayStack(int capacity){
            this.items = new Object[capacity];
            this.count = 0;
            this.n = capacity;
        }
    
        /**
         * 入栈操作
         */
        public boolean push(E e ){
    
            // 检查栈是否满
            if(count == n){
                return false;
            }
    
            // 将元素放入栈中
            items[count ++] = e;
            return true;
        }
    
        /**
         * 出栈操作
         */
        public E pop(){
            // 判断栈是否空
            if(count == 0){
                return null;
            }
    
            // 返回下标为count-1的元素,并且下标-1
            E e = (E)items[count - 1];
            count --;
    
            return e;
        }
    
        public int getCount() {
            return count;
        }
    
        public int getN() {
            return n;
        }
    }

    测试代码:

    package com.anan.struct.linetable;
    
    /**
     * 测试栈
     */
    public class ArrayStackTest {
    
        public static void main(String[] args) {
            // 创建栈对象
            ArrayStack<Integer> stack = new ArrayStack<Integer>(10);
    
            // 入栈操作
            System.out.println("1.入栈操作-----------------------------");
            for (int i = 0; i < 5; i++) {
                stack.push(i);
                System.out.println("当前入栈元素:" + i);
            }
            System.out.println("出栈前栈中元素个数:" + stack.getCount());
    
            System.out.println("2.出栈操作-----------------------------");
            // 出栈操作
            for (int i = 0; i < 5; i++) {
                System.out.println("当前出栈元素:" + stack.pop());
            }
    
            System.out.println("出栈后栈中元素个数:" + stack.getCount());
        }
    }

    测试结果:

    D:2teach1softjdk8injava com.anan.struct.linetable.ArrayStackTest
    1.入栈操作-----------------------------
    当前入栈元素:0
    当前入栈元素:1
    当前入栈元素:2
    当前入栈元素:3
    当前入栈元素:4
    出栈前栈中元素个数:5
    2.出栈操作-----------------------------
    当前出栈元素:4
    当前出栈元素:3
    当前出栈元素:2
    当前出栈元素:1
    当前出栈元素:0
    出栈后栈中元素个数:0
    
    Process finished with exit code 0

    4.讨论分享

    #考考你答案:
    1.你能用自己的话描述栈吗?
      1.1.栈是基于线性表的数据结构
      1.2.栈一种操作受限的数据结构
      1.3.栈满足后进先出的特点
      1.4.栈只允许在栈顶插入元素、和删除元素
      
    2.你知道栈都有哪些常见的应用场景吗?
      2.1.方法调用
        a.在jvm内存结构中,有线程共享的:方法区、堆
        b.在jvm内存结构中,有线程私有的:程序计数器、本地方法栈、虚拟机栈
        c.在虚拟机栈中,每个方法调用都被封装成:栈帧
        d.栈帧内容包含:局部变量表、操作数栈、方法出口信息等
        e.每个方法的调用过程,就是栈帧在虚拟机栈中入栈和出栈过程
        
      2.2.表达式求值
        a.假设有一个表达式:1+1024*1-1
        b.计算机中,如何求解该表达式的值呢?
        c.注意:当然不是人为口算
        d.我们的目的是让计算机能够理解任意表达式
      2.3.表达式求值过程
        a.用两个栈实现表达式求值
        b.一个用于存储数据:操作数栈
        c.一个用于存储运算符:运算符栈
        
        d.从左至右,读取表达式内容
        e.如果是数据,入栈到操作数栈中
        f.如果是运算符,入栈到运算符栈中
        
        g.比较运算符的优先级
        h.如果遇到高优先级的运算符,则将操作数栈的数据出栈
        i.进行计算,把新的计算结果重新入栈到操作数栈
        j.以此类推...直到处理完成整个表达式

    jvm内存结构:

    表达式求值过程:1+1024*1-1

  • 相关阅读:
    linux下文件搜索命令学习笔记
    【转】C++格式化输出
    UNIX中的文件类型
    Unix内核中打开文件的表示
    网络编程学习笔记:linux下的socket编程
    TCP协议学习笔记(一)首部以及TCP的三次握手连接四次挥手断开
    C/C++源代码从写完到运行发生了什么
    C++ 函数形参发生动态绑定时指针增长步长与静态类型一致
    C++中为什么要将析构函数定义成虚函数
    C++求一个十进制的二进制中1的个数
  • 原文地址:https://www.cnblogs.com/itall/p/12382409.html
Copyright © 2020-2023  润新知