探索数据结构(让数据结构不再成为幻想)

目录

什么是数据结构

数据与结构

什么是算法

复杂度分析

时间复杂度与空间复杂度

时间复杂度

思考:

空间复杂度

常数阶O(1)

对数阶O(logn)

线性阶O(n)

以下为空间复杂度为O(n)

线性对数阶O(nlogn)

平方阶O(n)

指数阶O(2^n)

什么是数据结构

数据结构是由:“数据”与“结构”两部分组成

数据与结构

数据:如我们所看见的广告、图片、视频等,常见的数值,教务系统里的(姓名、性别、学号、学历等等);

结构:当我们面对海量的数据时,我们时常无法下手,寻找数据是不方便的,可读性就很差;而结构则是将这些数据以各种不同的形式进行排序,使我们便于寻找;

数据结构:是计算机存储、组织数据的方式。是数据之间存在一种或多种相互关系的集合;

什么是算法

算法(Algorithm)就是定义良好的计算过程,他取出一个或一组数据为输入,产出一个或一组的值为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果。

算法一般分为:排序,递归与分治,回溯,DP,贪心,搜索算法、二分查找、水桶法等等;

  • 算法往往数学密切相关,就如数学题一样,每道数学题都有不同的解法,算法也是同理

复杂度分析

我们如何评判算法的效率呢,问题的解决方法有很多,对于计算机而言,我们需要找到问题的最优解,为了寻找到这个最优解,我们需要从两个维度评判

  • 时间效率:算法运行的快慢
  • 空间效率:算法所占空间的大小

评估方法:实验分析与理论分析

对于实验分析而言:

  • 相同的算法在不同的电脑,它们所运行的时间也许会有很大的出入;
  • 当面对大量的数据而言,同一台电脑时间上的差距则会变为很大,导致误差的增大;
  • 有些算法在少量数据时运算速度不快,在大量数据中反之;

由于实验分析法的局限性,就有人提出了一种理论测评的方法,就是渐近复杂度分析(asymptotic complexity analysis),简称复杂度分析

这种方法体现算法运行所需的时间(空间)资源与输入数据大小之间的关系,能有效的反应算法的优劣。

时间复杂度与空间复杂度

时间复杂度

指一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。让我们计算下方代码的时间复杂度

int main()
{int n=10;//对于时间复杂度而言,当数据为n时,下方代码区,运行次数10,时间复杂度为O(n)while (n--) {printf("%d", n);}//在时间复杂度中,我们会忽略除最高次的所有项//忽略所有系数return 0;
}

实际上我们不可能对执行次数的统计精确,并且为理论分析,当n->∞时,最高次的影响会远远超过非最高次的项,所以O(n)的数量级由最高次决定,所以当我们计算时间复杂度时,可以简化为以下两个步骤

  • 忽略除最高次的所有项
  • 忽略所有系数
思考:

当我们遍历下方数组,查找2时,我们需要4次;

当长度为n的数组中存放的是无序自然数时,他们是没有规则的,此时我们查找2的次数:[ 1 , n ]

此时我们需要将最坏的情况作为时间复杂度

空间复杂度

空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度的表示也遵循大O的渐进表示法

让我们计算一下冒泡排序的空间复杂度

// 计算BubbleSort的空间复杂度?
void BubbleSort(int* a, int n)
{assert(a);for (size_t end = n; end > 0; --end){int exchange = 0;for (size_t i = 1; i < end; ++i){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = 1;}}if (exchange == 0)break;}
}//在冒泡排序中,我们只开辟了一块空间,所以空间复杂度为O(1);

复杂度的分类

算法的复杂度有几个量级,表示如下:

O(1)<O(logN)<O(N)<O(NlogN)<O(N2)<O(2N)<O(N!)

如图下列: 

常数阶O(1)
int main()
{int n = 4;while (n--) {printf("%d", n);//执行次数为常数}return 0;
}
对数阶O(logn)
int binary_search(int nums[], int size, int target)
//nums是数组,size是数组的大小,target是需要查找的值
{ int left = 0;int right = size - 1;	// 定义了target在左闭右闭的区间内,[left, right]while (left <= right) {	//当left == right时,区间[left, right]仍然有效int middle = left + ((right - left)>>1);//等同于 (left + right) / 2,防止溢出if (nums[middle] > target) {right = middle - 1;	//target在左区间,所以[left, middle - 1]} else if (nums[middle] < target) {left = middle + 1;	//target在右区间,所以[middle + 1, right]} else {	//既不在左边,也不在右边,那就是找到答案了return middle;}}//没有找到目标值return -1;
}
线性阶O(n)
int main()
{int n;scanf("%d", &n);int court = 0;for (int i = 0; i < n; i++) {court += i;//计算和}return 0;
}
以下为空间复杂度为O(n)
int main()
{int n;scanf("%d", &n);int* p = (int*)malloc(sizeof(int) * n);//开辟大小为n的空间if (p == NULL){perror("malloc fail");return -1;}free(p);p = NULL;}
线性对数阶O(nlogn)

无论是时间复杂度还是空间复杂度,线性对数阶都是在循环嵌套里实现,即为一层为O(n),另一层为O(logn);

所以我们可以利用二分查找+打印

int binary_search(int nums[], int size, int target) //nums是数组,size是数组的大小,target是需要查找的值
{int left = 0;int right = size - 1;	// 定义了target在左闭右闭的区间内,[left, right]while (left <= right) {	//当left == right时,区间[left, right]仍然有效int middle = left + ((right - left) / 2);//等同于 (left + right) / 2,防止溢出if (nums[middle] > target) {right = middle - 1;	//target在左区间,所以[left, middle - 1]}else if (nums[middle] < target) {left = middle + 1;	//target在右区间,所以[middle + 1, right]}else {	//既不在左边,也不在右边,那就是找到答案了printf("%d ", nums[middle]);}}//没有找到目标值return -1;
}void func(int nums[], int size, int target)
{for (int i = 0; i < size; i++){binary_search(nums, size, target);}
}
平方阶O(n)

莫过于我们最为熟悉的冒泡排序

void BubbleSort(int* a, int n)
{assert(a);for (size_t end = n; end > 0; --end){int exchange = 0;for (size_t i = 1; i < end; ++i){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = 1;}}if (exchange == 0)break;}
}
指数阶O(2^n)

指数阶的算法效率低下,并不常见

最为常见的指数阶为递归实现斐波那契数列

int Fib1(int n)
{if (n == 1 || n == 2){return 1;}else{return Fib1(n - 1) + Fib1(n - 2);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/836058.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WHAT - CSS Animationtion 动画系列(二)

目录 一、循环波浪二、关键帧呼应三、关键帧顺接四、利用 transform-origin 做拉伸五、大元素可拆分多个小元素联动六、预留视觉缓冲七、随机感&#xff1a;动画周期设置八、抛物线&#xff1a;两个内外div实现x和y向量运动 今天我们主要学习动画实现要素。 一、循环波浪 利用…

类加载机制(双亲委派机制)

文章目录 JVM的作用是什么双亲委派机制加载流程 JVM的作用是什么 我们运行Java程序时&#xff0c;要安装JDK&#xff0c;JDK包含JVM&#xff0c;不同环境的JDK都是不同的。 Java 代码在编译后会形成 class 的字节码文件&#xff0c;该字节码文件通过 JVM 解释器&#xff0c;生…

音视频-H264编码封装- MP4格式转Annex B格式

目录 1&#xff1a;H264语法结构回顾 2&#xff1a;H264编码补充介绍 3&#xff1a;MP4模式转Annex B模式输出到文件示例 1&#xff1a;H264语法结构回顾 在之前文章里介绍过H264的语法结构。 传送门: 视音频-H264 编码NALU语法结构简介 2&#xff1a;H264编码补充介绍 H…

泽众财务RPA机器人常见五个应用场景

泽众RPA&#xff08;即机器人流程自动化&#xff0c;Robotic Process Automation, RPA&#xff09;解决方案是依托于各类先进信息技术手段的虚拟劳动力 &#xff08;数字劳动力&#xff09;&#xff0c;根据预先设定的程序操作指令对任务进行自动化处理&#xff0c;实现业务流程…

网络安全等级保护的发展历程

1994年国务院147号令第一次提出&#xff0c;计算机信息系统实行安全等级保护&#xff0c;这也预示着等保的起步。 2007年《信息安全等级保护管理办法》的发布之后。是等保在各行业深耕落地的时代。 2.0是等保版本的俗称&#xff0c;不是等级。等保共分为五级&#xff0c;二级…

JeeSite V5.7.0 发布,Java快速开发平台,Vite5、多项重构重磅升级

JeeSite V5.7.0 发布&#xff0c;Java快速开发平台&#xff0c;Vite5、多项重构重磅升级 升级内容 新增 参数配置 IP 地址黑白名单过滤器动态参数 新增 侧边栏是否展开第一个菜单的开关 first-open 新增 AesTypeHandler 处理字段数据加密解密或脱敏 新增 JsonTypeHandler …

AI换脸原理(7)——人脸分割参考文献TernausNet: 源码解析

1、介绍 这篇论文相对来说比较简单,整体是通过使用预训练的权重来提高U-Net的性能,实现对UNet的改进。该方法也是DeepFaceLab官方使用的人脸分割方法。在介绍篇我们已经讲过了UNet的网络结构和设计,在进一步深入了解TernausNet之前,我们先简单回顾下UNet。 U-Net的主要结构…

网络基础(三)——网络层

目录 IP协议 1、基本概念 2、协议头格式 2.1、报头和载荷如何有效分离 2.2、如果超过了MAC的规定&#xff0c;IP应该如何做呢&#xff1f; 2.3、分片会有什么影响 3、网段划分 4、特殊的ip地址 5、ip地址的数量限制 6、私有ip地址和公网ip地址 7、路由 IP协议 网络…

Docker尚硅谷_高级篇

Docker尚硅谷 高级篇一、Dockerfile1.1 Dockerfile1.2 构建过程1.3 Dockerfile保留字1.3 构建镜像1.4 虚悬镜像 二、Docker发布微服务2.1 搭建SpringBoot项目2.2 发布微服务项目到Docker容器 三、Docker网络3.1 Docker网络3.2 docker网络命令3.3 Docker网络模式3.4 docker03.5 …

sql注入之bool盲注

目录 盲注步骤 1、进入靶场 2、如下图所示输入&#xff1f;id1‘ 判断此时存在注入点 3、判断列数 ​编辑 4、开始盲注 普通的python脚本 代码思想 结果 二分查找python脚本 二分查找算法思想简介 二分查找与普通查找的主要差距 代码思想 代码 结果​编辑 下面以…

后端项目开发笔记

Maven打包与JDK版本不对应解决方法 我这里使用jdk8。 <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configurat…

趣味软件-吃什么(Eat What)?

&#x1f354;&#x1f35c;&#x1f355; 你是否也有这样的日常烦恼&#xff1f; 每天的“世纪难题”——今天吃什么&#xff1f; &#x1f570;️ 饭点到了&#xff0c;脑袋空空&#xff0c;选择困难症大爆发&#xff01; &#x1f46b; 和女朋友约会&#xff0c;却不知道她的…

HackMyVM-Minimal

目录 信息收集 arp nmap nikto whatweb WEB web信息收集 gobuster 文件包含漏洞 提权 web信息收集 main方法 question_1 question_2 question_3 prize.txt 软连接 信息收集 arp ┌──(root?0x00)-[~/HackMyVM] └─# arp-scan -l Interface: eth0, type: E…

.NET_NLog

步骤 1. 添加依赖 ①Microsoft.Extensions.DependencyInjection ②NLog.Extensions.Logging&#xff08;或Microsoft.Extensions.Logging.___&#xff09; Tutorial NLog/NLog Wiki GitHub 2.添加nlog.config文件(默认名称, 可改为其他名称, 但需要另行配置) 文件的基础…

基于Java+SpringBoot+Mybaties-plus+Vue+elememt 驾校管理 设计与实现

一.项目介绍 系统角色&#xff1a;管理员、驾校教练、学员 管理员&#xff1a; 个人中心&#xff1a;修改密码以及个人信息修改 学员管理&#xff1a;维护学员信息&#xff0c;维护学员成绩信息 驾校教练管理&#xff1a;驾校教练信息的维护 驾校车辆管理&…

【数据结构初阶】直接插入排序

最近浅学了直接插入排序&#xff0c;写个博客做笔记&#xff01;笔记功能除外若能对读者老爷有所帮助最好不过了&#xff01; 直接插入排序是插入排序的一种&#xff0c;那么介绍直接插入排序之前先介绍一下常见的排序算法&#xff01; 目录 1.常见的排序算法 2.直接插入排…

57. 【Android教程】相机:Camera

相机现在已经不仅仅是手机必备神器了&#xff0c;甚至相机的拍照质量已经是很多人买手机的首选条件了。而对于相机而言主要有两大功能&#xff1a;拍照片和拍视频。Android 为此两种方式&#xff1a; 相机 intent相机 API 本节我们就一起来看看相机的具体用法。 1. 打开 Camer…

C# Linq中的自定义排序

1.开发过程中&#xff0c;会遇到OrderBy/OrderByDescending排序无法满足的情况&#xff0c;此时就需要自定义排序&#xff0c;按照想要的排序规则取排序&#xff0c;比如订单的状态等等。 2.自定义泛型比较器代码如下&#xff1a; /// <summary>/// 自定义泛型比较器(用…

train_gpt2_fp32.cu - layernorm_forward_kernel3

源码 __global__ void layernorm_forward_kernel3(float* __restrict__ out, float* __restrict__ mean, float* __restrict__ rstd,const float* __restrict__ inp, const float* __restrict__ weight,const float* __restrict__ bias, int N, int C) {cg::thread_block bl…

【北京迅为】《iTOP-3588从零搭建ubuntu环境手册》-第8章 安装编译所需要的依赖包

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…