文章目录
- 一. 思维导图
- 二. 栈的概念
- 1. 定义
- 2. 栈的内存分配
- 3. 栈的分类
- (1). 顺序栈(静态栈)
- (2). 链栈(动态栈)
- 三. 栈的存储结构
- 1. 顺序栈
- (1). 定义
- (2). 顺序栈的数据结构表示
- (3). 顺序栈的基本操作
- (4). 顺序栈的特例(共享栈)
- 2. 链栈
- (1). 定义
- (2). 链栈数据结构表示
- (3). 链栈算法的操作
- 四. 栈的应用
- 1. 函数调用
- 2. 中断
- 3. 表达式求值
- 4. 缓冲处理
- 5. 走迷宫
- 6. 括号匹配
- 7. 递归中的应用
- 7.1 概述
- 7.2 递归的本质
- 7.3 常用递归算法
- 7.4 递归的应用
一. 思维导图
二. 栈的概念
1. 定义
- 栈(stack)只允许在一端进行插入和删除操作的线性表
- 或者说是一种可以实现“先进后出”的存储结构
- 栈是一种操作受限的线性表
2. 栈的内存分配
内存分配方式理解:栈和堆不同
- m,q,i,p变量是栈分配
- 200,100存储是堆分配
3. 栈的分类
(1). 顺序栈(静态栈)
- 类似数组
(2). 链栈(动态栈)
- 类似链表
1. 顺序栈
(1). 定义
- 采用顺序存储结构(用一组地址连续的存储单元存放栈底到栈顶的元素)
(2). 顺序栈的数据结构表示
(3). 顺序栈的基本操作
(4). 顺序栈的特例(共享栈)
定义
- 两个栈的栈底分别设置在共享空间的两端,栈顶向共享空间的中间延伸,共享一个一维数组空间
共享栈的算法基本操作
放代码
2. 链栈
(1). 定义
- 采用链式存储的栈,一般采用单链表实现
优点:
- 便于多个栈共享存储空间和提高效率,不存在栈满上溢
(2). 链栈数据结构表示
(3). 链栈算法的操作
https://gitee.com/zhiqiang99/data-structure/blob/master/Stack/stack.cpp
- 栈的基本操作
- 2. 初始化一个栈
- 3. 压栈
- 4. 遍历栈
1. 函数调用
2. 中断
3. 表达式求值
4. 缓冲处理
5. 走迷宫
6. 括号匹配
7. 递归中的应用
7.1 概述
递归定义:
- 一个函数自己直接或间接调用自己
不同函数之间的相互调用
一个函数自己调用自己
7.2 递归的本质
递归满足三个条件:
- 递归必须得有一个明确的中止条件
- 该函数所处理的数据规模必须在递减(值可以增加)
- 这个转换必须是可解的
循环和递归的关系
- 理论上所有的循环都可转换成递归(方法很多:基本上是一个数学问题)
- 但用递归解决的问题用循环不一定能解决
递归的特点:
- 优点:易于理解
- 缺点:速度慢,存储空间大
循环的特点:
- 缺点:不易理解
- 优点:速度快,存储空间小
7.3 常用递归算法
阶乘的循环实现
https://gitee.com/zhiqiang99/data-structure/blob/master/Stack/Recursion/Factorial_circle.cpp递归实现求阶乘功能
https://gitee.com/zhiqiang99/data-structure/blob/master/Stack/Recursion/Factorial_recursion.cpp计算1-100的和,使用递归来实现
https://gitee.com/zhiqiang99/data-structure/blob/master/Stack/Recursion/1_100_sum.cpp- 汉诺塔实现
https://gitee.com/zhiqiang99/data-structure/blob/master/Stack/Recursion/Hanoi.cpp
7.4 递归的应用
计算机特别适合用递归的思想解决问题,但是我们人类用递归思想来考虑问题就会感到十分困难,对计算机而言,一个函数调用别的函数与调用它自己是没有区别的。对机器而言,递归和普通函数的调用没有区别,都是借用堆栈把函数的返回地址,函数的局部变量,调用函数的实参压栈。但对人而言,自己调用自己,觉得不可思议,应该陷入死循环才对嘛
递归思想是软件思想的最基本思想之一,在树和图论上面,几乎全是用递归来实现的。最简单的,大家用的资源管理器,我要求无之尽的创建用户目录。这实际上就是动态构造树的问题,要用到递归的知识来解决。
- 树和森林就是以递归的方式定义的(易理解,若不用递归将非常难实现)
- 树和图的很多算法都是以递归来实现的
- 很多数学公式就是以递归的方式定义的(斐波那契数列)
未完待续…