文章目录

  • ​​一. 思维导图​​
  • ​​二. 栈的概念​​
  • ​​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)只允许在一端进行插入和删除操作的线性表
  • 或者说是一种可以实现“先进后出”的存储结构
  • 栈是一种操作受限的线性表

数据结构——线性结构的常见应用(栈)_顺序栈_02

2. 栈的内存分配

内存分配方式理解:栈和堆不同

#include <stdio.h>
#include <malloc.h>
{
void f(int k){
int m;
double * p = (double *)malloc (200);
}

int main(void){
int i = 10;
int * p = (int *)malloc(100);
return 0;
}
}
  • m,q,i,p变量是栈分配
静态分配(由OS分配)压栈出栈
或局部变量分配
  • 200,100存储是堆分配
动态分配(程序员手动分配)
堆排序方式分配内存

3. 栈的分类

(1). 顺序栈(静态栈)

  • 类似数组

(2). 链栈(动态栈)

  • 类似链表
  • 数据结构——线性结构的常见应用(栈)_顺序栈_03


三. 栈的存储结构

1. 顺序栈

(1). 定义

  • 采用顺序存储结构(用一组地址连续的存储单元存放栈底到栈顶的元素)

(2). 顺序栈的数据结构表示

数据结构——线性结构的常见应用(栈)_Stack_04

(3). 顺序栈的基本操作

数据结构——线性结构的常见应用(栈)_递归_05

(4). 顺序栈的特例(共享栈)

定义

  • 两个栈的栈底分别设置在共享空间的两端,栈顶向共享空间的中间延伸,共享一个一维数组空间

数据结构——线性结构的常见应用(栈)_Stack_06


共享栈的算法基本操作

放代码

2. 链栈

(1). 定义

  • 采用链式存储的栈,一般采用单链表实现

优点:

  • 便于多个栈共享存储空间和提高效率,不存在栈满上溢

(2). 链栈数据结构表示

数据结构——线性结构的常见应用(栈)_递归_07

(3). 链栈算法的操作

​https://gitee.com/zhiqiang99/data-structure/blob/master/Stack/stack.cpp​

  1. 栈的基本操作
  2. 数据结构——线性结构的常见应用(栈)_Stack_08

  3. 2. 初始化一个栈
  4. 数据结构——线性结构的常见应用(栈)_Stack_09

  5. 3. 压栈
  6. 数据结构——线性结构的常见应用(栈)_c语言_10

  7. 4. 遍历栈
  8. 数据结构——线性结构的常见应用(栈)_数据结构_11

四. 栈的应用

1. 函数调用

数据结构——线性结构的常见应用(栈)_顺序栈_12

2. 中断

3. 表达式求值

4. 缓冲处理

5. 走迷宫

6. 括号匹配

7. 递归中的应用

7.1 概述

递归定义:

  • 一个函数自己直接或间接调用自己

不同函数之间的相互调用

数据结构——线性结构的常见应用(栈)_数据结构_13

一个函数自己调用自己

数据结构——线性结构的常见应用(栈)_c语言_14

7.2 递归的本质

数据结构——线性结构的常见应用(栈)_Stack_15

递归满足三个条件:

  1. 递归必须得有一个明确的中止条件
  2. 该函数所处理的数据规模必须在递减(值可以增加)
  3. 这个转换必须是可解的

循环和递归的关系

  • 理论上所有的循环都可转换成递归(方法很多:基本上是一个数学问题)
  • 但用递归解决的问题用循环不一定能解决

递归的特点:

  • 优点:易于理解
  • 缺点:速度慢,存储空间大

循环的特点:

  • 缺点:不易理解
  • 优点:速度快,存储空间小

7.3 常用递归算法

  1. 阶乘的循环实现
    ​https://gitee.com/zhiqiang99/data-structure/blob/master/Stack/Recursion/Factorial_circle.cpp​

  2. 递归实现求阶乘功能
    ​https://gitee.com/zhiqiang99/data-structure/blob/master/Stack/Recursion/Factorial_recursion.cpp​

  3. 计算1-100的和,使用递归来实现
    ​https://gitee.com/zhiqiang99/data-structure/blob/master/Stack/Recursion/1_100_sum.cpp​

  4. 汉诺塔实现
    ​https://gitee.com/zhiqiang99/data-structure/blob/master/Stack/Recursion/Hanoi.cpp​
  5. 数据结构——线性结构的常见应用(栈)_顺序栈_16


  6. 数据结构——线性结构的常见应用(栈)_顺序栈_17

7.4 递归的应用

计算机特别适合用递归的思想解决问题,但是我们人类用递归思想来考虑问题就会感到十分困难,对计算机而言,一个函数调用别的函数与调用它自己是没有区别的。对机器而言,递归和普通函数的调用没有区别,都是借用堆栈把函数的返回地址,函数的局部变量,调用函数的实参压栈。但对人而言,自己调用自己,觉得不可思议,应该陷入死循环才对嘛

递归思想是软件思想的最基本思想之一,在树和图论上面,几乎全是用递归来实现的。最简单的,大家用的资源管理器,我要求无之尽的创建用户目录。这实际上就是动态构造树的问题,要用到递归的知识来解决。

  • 树和森林就是以递归的方式定义的(易理解,若不用递归将非常难实现)
  • 树和图的很多算法都是以递归来实现的
  • 很多数学公式就是以递归的方式定义的(斐波那契数列)

未完待续…