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

一. 思维导图

在这里插入图片描述

二. 栈的概念

1. 定义

  • 栈(stack)只允许在一端进行插入和删除操作的线性表
  • 或者说是一种可以实现“先进后出”的存储结构
  • 栈是一种操作受限的线性表

在这里插入图片描述

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). 链栈(动态栈)

  • 类似链表
    在这里插入图片描述

三. 栈的存储结构

1. 顺序栈

(1). 定义

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

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

在这里插入图片描述

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

在这里插入图片描述

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

定义

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

在这里插入图片描述
共享栈的算法基本操作
放代码

2. 链栈

(1). 定义

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

优点:

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

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

在这里插入图片描述

(3). 链栈算法的操作

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

  1. 栈的基本操作
    在这里插入图片描述
    2. 初始化一个栈
    在这里插入图片描述
    3. 压栈
    在这里插入图片描述
    4. 遍历栈

    在这里插入图片描述

四. 栈的应用

1. 函数调用

在这里插入图片描述

2. 中断

3. 表达式求值

4. 缓冲处理

5. 走迷宫

6. 括号匹配

7. 递归中的应用

7.1 概述

递归定义:

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

不同函数之间的相互调用
在这里插入图片描述

一个函数自己调用自己
在这里插入图片描述

7.2 递归的本质

在这里插入图片描述

递归满足三个条件:

  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在这里插入图片描述
    在这里插入图片描述

7.4 递归的应用

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

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

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

未完待续…

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值