算法的复杂度
1.数据结构前言
下面的概念有的比较难理解,做个了结就行。
1.1数据结构的起源
在现实生活中我们更多地并不是解决数值计算的问题,而是 需要一些更科学的手段如(表,数,图等数据结构),才能更好地处理问题。所以数据结构是一门研究非数值计算的程序设计问题中的操作对象,以及他们之间的关系和操作等相关问题的学科。
1968年,美国高德纳教授在其所写的《计算机程序设计艺术》第一卷《基本算法》中,较系统的阐述了数据的逻辑结构及其操作。
1.2数据结构(Data Structure)的定义
数据结构:相互之间存在一种或者多种关系的数据元素的集合
数据元素:是组成数据的,有一定意义的基本单位,在计算机中被当做成体处理。也叫做记录。比如在人类社会中,它的数据元素就是人。畜类中,牛羊猪等就是它的数据元素。
数据项:一个数据元素可以由多个数据项组成。比如人的数据项可以由眼睛、鼻子、嘴巴等等。
数据对象:具有相同性质的数据元素的集合,是数据的子集。比如人都有生日、姓名、性别,把这些拥有相同数据项的数据元素就称为相同性质的数据元素。
1.3逻辑结构与物理结构
1.3.1逻辑结构
逻辑结构:数据元素之间的相互关系。
常见的逻辑结构:
集合结构:(”平等“)
线性结构:(一对一)
树形结构:(一对多)
图形结构:(多对多)
1.3.2物理结构
物理结构:指的是数据的逻辑结构在计算机中的存储方式
存储结构的分类:顺序存储结构、链式存储结构
顺序存储结构:把数据元素存放在连续的内存空间中,这种的结构的物理结构与逻辑结构是相同的
链式存储结构:把数据元素存放在任意的内存空间中,这个任意可以连续也可以不连续。
这种存储结构的操作是建立在指针域上的,因为你总得通过一个手段去找到这些元素。
1.4抽象数据类型
1.4.1数据类型
数据类型:只一组具有相同性质的值的集合以及定义在此集合上面的一组操作的总称。
高级语言中,类型往往指代的是变量、常量、表达式所能表示的范围,还有所能进行的+ - * /等一系列操作。
在C语言中,数据类型分为:
原子类型:不可再分的基本单位,包括整形、浮点型、字符型
结构类型:由若干个类型组合而成,可以再分。比如:一个整形数组就包含若干个整形数据。
1.4.2抽象数据类型
抽象是指抽出事物具有的本质属性。
抽象数据类型:是指一个数学模型以及定义在该模型上面的一组操作。
对于抽象数据类型,我们并不关注数据本身的物理结构,而是关注它的数学抽象特征。
一个抽象数据类型定义了:一个数据对象、数据元素中各数据元素之间的关系及对数据的操作。
2.算法的复杂度
在次之前我们先看一个例题:189. 轮转数组 - 力扣(LeetCode)
经过考虑我们可以有三种解法:
1.挨个轮转
void rotate(int* nums, int numsSize, int k) {int i=0;while(k--){int tmp=nums[numsSize-1];for(i=numsSize-1;i>0;i--){nums[i]=nums[i-1];}nums[0]=tmp;}
}
2.取余挨个轮转:
void rotate(int* nums, int numsSize, int k) {int i=0;k%=numsSize;while(k--){int tmp=nums[numsSize-1];for(i=numsSize-1;i>0;i--){nums[i]=nums[i-1];}nums[0]=tmp;}
}
3.面向结果编程:
void rotate(int* nums, int numsSize, int k) {int ans[numsSize];int i=0;for(i=0;i<numsSize;i++){ans[(i+k)%numsSize]=nums[i];}for(i=0;i<numsSize;i++){nums[i]=ans[i];}}
4.三次逆序法:
void Reverse(int* nums,int low,int high){while(low<high){int tmp=nums[low];nums[low]=nums[high];nums[high]=tmp;low++;high--;}
}
void rotate(int* nums, int numsSize, int k) {k%=numsSize;Reverse(nums,0,numsSize-k-1);Reverse(nums,numsSize-k,numsSize-1);Reverse(nums,0,numsSize-1);}
2.1时间复杂度
先说明一下:上述方法的1、2的关系为优化。3、4是使用了不同的算法。
2.1.1时间复杂度的定义
时间复杂度:在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)数量级。算法的时间复杂度,也就是算法的时间量度,记作T(n)=O(f(n))。它表示随着问题规模n的增大,算法的执行时间的增长率和符f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度。其中符f(n)是问题规模n的某个函数。
这里我们从定义中提取几个关键点:
1.算法时间复杂度是算法渐进时间复杂度的简称。
2.它表示的是一种变化趋势(随问题规模)或者增长率。
3.并不是一个确切的语句到底执行多少次的函数表达式。
2.1.2算法时间复杂度的大O渐进表示法
💡 推导⼤O阶规则1. 时间复杂度函数式 T(N) 中,只保留最⾼阶项,去掉那些低阶项,因为当 N 不断变大时,低阶项对结果影响越来越小,当 N 无穷大时,就可以忽略不计了。2. 如果最高阶项存在且不是 1 ,则去除这个项目的常数系数,因为当 N 不断变大,这个系数对结果影响越来越小,当 N 无穷大时,就可以忽略不计了。3. T(N) 中如果没有 N 相关的项目,只有常数项,用常数 1 取代所有加法常数。
2.1.3算法时间复杂度的例题:
2.1.3.1
void Func2(int N)
{
int count = 0;
for (int k = 0; k < 2 * N ; ++ k)
{
++count;
}
int M = 10;
while (M--)
{
++count;
}
printf("%d\n", count);
}
T(n)=2*n+10(只关注循环的额外开销)
时间复杂度:O(n)
2.1.3.2
void Func3(int N, int M)
{
int count = 0;
for (int k = 0; k < M; ++ k)
{
++count;
}
for (int k = 0; k < N ; ++
k)
{
++count;
}
printf("%d\n", count);
}
同样的时间复杂度:O(n)
2.1.3.3
void Func4(int N)
{
int count = 0;
for (int k = 0; k < 100; ++ k)
{
++count;
}
printf("%d\n", count);
}
O(1)
2.1.3.4
const char * strchr ( const char
* str, int character)
{
const char* p_begin = s;
while (*p_begin != character)
{
if (*p_begin == '\0')
return NULL;
p_begin++;
}
return p_begin;
}
这是一个查找某个字符的算法,但是不同情况有不同的复杂度有不同划分:
假设要找的就在第一个字符位置(或常数个):T(n)=k(常数) --> O(1)4
假设要找的在最后一个位置:T(n)=n --> O (n)
假设要找的在中间:T(n)=n/2 --> O(n)
2.1.3.5
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;
}
}
T(n)=N*(N+1)/2 -->O(n)=n^2
2.1.3.6
void func5(int n)
{
int cnt = 1;
while (cnt < n)
{
cnt *= 2;
}
}
O(n)=logn 这里写成lnn lgn都行,因为我们说时间复杂度表示的是变化率,所以只需要表示出来对数阶就可以。
2.1.3.7
递归的时间复杂度
// 计算阶乘递归Fac的时间复杂度?
long long Fac(size_t N)
{
if(0 == N)
return 1;
return Fac(N-1)*N;
}
O(n)=n
递归时间复杂度的求法=单次递归的时间复杂度*递归次数
2.1.4常见的时间复杂度
2.2.空间复杂度
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)
3.轮转数组复杂度分析
法一:O(n^2) O(1)
法二:O(n^2) O(1)
法三:O(n) O(n)
法四:O(n) O(1)
完
相关文章:

算法的复杂度
1.数据结构前言 下面的概念有的比较难理解,做个了结就行。 1.1数据结构的起源 在现实生活中我们更多地并不是解决数值计算的问题,而是 需要一些更科学的手段如(表,数,图等数据结构),才能更好…...

Linux命令进阶·如何切换root以及回退、sudo命令、用户/用户组管理,以及解决创建用户不显示问题和Ubuntu不显示用户名只显示“$“符号问题
目录 1. root用户(超级管理员) 1.1 用于账户切换的系统命令——su 1.2 退回上一个用户命令——exit 1.3 普通命令临时授权root身份执行——sudo 1.3.1 为普通用户配置sudo认证 2. 用户/用户组管理 2.1 用户组管理 2.2 用户管理 2.2.1 …...

若依项目源码阅读
源码阅读 前端代码分析 代码生成器生成的前端代码有两个,分别是course.js用于向后端发送ajax请求的接口代码,另一个是index.vue,用于在浏览器展示课程管理的视图组件。前端的代码是基于vue3elementplus。 template用于展示前端组件别的标签…...

JVM知识点学习-1
学习视频:狂神说Java 类加载器和双亲委派机制 类加载器 作用:加载Class文件 流程:这里的名字car1。。在栈里面,但是数据在堆里面 类加载器的几个类型: 虚拟机自带的类加载器;启动类(根Boot…...

TypeScript和JavaScript区别详解
文章目录 TypeScript和JavaScript区别详解一、引言二、类型系统1、静态类型检查TypeScript 示例JavaScript 示例 2、类型推断TypeScript 示例JavaScript 示例 三、面向对象编程TypeScript 示例JavaScript 示例 四、使用示例1. 环境搭建2. 创建TypeScript项目3. 安装TypeScript插…...

RVO动态避障技术方案介绍
原文:RVO动态避障技术方案介绍 - 哔哩哔哩 我们在开发游戏的时候经常会遇到这样的问题,当我们寻路的时候,其它人也在寻路,如何避免不从其它人的位置穿过。这个叫做动态避障,目前主流的解决方案就是RVO。本节我们来介绍…...

Vue进阶之单组件开发与组件通信
书接上篇,我们了解了如何快速创建一个脚手架,现在我们来学习如何基于vite创建属于自己的脚手架。在创建一个新的组件时,要在新建文件夹中打开终端创建一个基本的脚手架,可在脚手架中原有的文件中修改或在相应路径重新创建…...

OGRE 3D----5. OGRE和QML事件交互
在现代图形应用程序开发中,OGRE(Object-Oriented Graphics Rendering Engine)作为一个高性能的3D渲染引擎,广泛应用于游戏开发、虚拟现实和仿真等领域。而QML(Qt Modeling Language)则是Qt框架中的一种声明式语言,专注于设计用户界面。将OGRE与QML结合,可以充分利用OGR…...
ARIMA-神经网络混合模型在时间序列预测中的应用
ARIMA-神经网络混合模型在时间序列预测中的应用 1. 引言 1.1 研究背景与意义 时间序列预测在现代数据科学中扮演着越来越重要的角色。从金融市场的价格走势到工业生产的需求预测,从气象数据的天气预报到用电量的负荷预测,时间序列分析无处不在。传统的统计方法和现代深度学习…...

常见靶场的搭建
漏洞靶场 渗透测试(漏洞挖掘)切忌纸上谈兵,学习渗透测试(漏洞挖掘)知识的过程中,我们通常需要一个包含漏洞的测试环境来进行训练。而在非授权情况下,对于网站进行渗透测试攻击,是触及…...

[MacOS] [kubernetes] MacOS玩转虚拟化最佳实践
❓ 为什么不在MacOS本机安装呢?因为M系列芯片是Arm架构,与生产环境或者在本地调试时候,安装虚拟镜像和X86不同,造成不必要的切换环境的额外成本,所以在虚拟化的x86调试 步骤 & 详情 一: 安装OrbStack & 并配置…...

HarmonyOS:@Provide装饰器和@Consume装饰器:与后代组件双向同步
一、前言 Provide和Consume,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递,Provide和Consume摆脱参数传递机制的束缚,实现跨层级传递。 其中Provi…...

git 上传代码时报错
在上传代码时,显示无法上传 PS E:\JavaWeb\vue3-project> git push To https://gitee.com/evening-breeze-2003/vue3.git! [rejected] master -> master (non-fast-forward) error: failed to push some refs to https://gitee.com/evening-breeze-20…...
判断1456789876541是否为素数,是输出“是素数“,不是则输出“不是素数“
题目描述 判断1456789876541是否为素数,是输出"是素数",不是则输出"不是素数" 代码实现 int main() { long long n 1456789876541; //for (long long i 2; i < n; i)//数据量太大 for(long long i2;i<sqrt(n);i)//素数的优化 { if (n % i 0) …...

Flutter:封装发送验证码组件,注册页使用获取验证码并传递控制器和验证码类型
验证码:view import package:flutter/material.dart; import package:get/get.dart; import index.dart;class SendcodePage extends GetView<SendcodeController> {// 接收注册页面,传进来的手机号控制器,和发送验证码的类型final Tex…...

亚马逊IP关联是什么?
亚马逊不仅提供了广泛的商品和服务,也是许多企业和个人选择的电子商务平台。然而,与亚马逊相关的IP关联问题,特别是在网络安全和运营管理方面,经常成为使用亚马逊服务的用户和商家关注的焦点。通过了解亚马逊IP关联的含义、可能的…...

Electron + vue3 打包之后不能跳转路由
路由不跳转问题原因: 是因为electron需要将vue-router的mode调整为hash模式(两种写法) export default new Router({mode: hash, //这里history修改为hashscrollBehavior: () > ({y: 0}),routes: constantRouterMap, }) export default new createRouter({his…...
docker安装clickhouse副本集群
docker安装clickhouse副本集群 1、clickhouse副本集群搭建1.1、docker安装zookeeper集群1.1.1、zookeeper第一个节点安装1.1.2、zookeeper第二个节点安装1.1.3、zookeeper第三个节点安装1.1.4、zookeeper客户端命令 2、Clickhouse副本集群搭建2.1、clickhouse搭建2.2、验证集群…...

vue超过三行显示省略号和查看更多按钮
1、超过3行显示省略号和更多按钮,不超过3行正常显示; html: <div class"container"><div style"display: flex;"><div class"content"><div class"text-content" ref"textContentR…...
【软考速通笔记】系统架构设计师⑤——软件工程基础知识
文章目录 一、前言二、基础知识点2.1 软件危机2.2 软件生命周期 三、软件过程模型(论文)3.1 瀑布模型3.2 原型模型3.3 螺旋模型3.4 敏捷模型3.5 软件统一过程模型3.6 软件成熟度模型3.7 软件成熟度模型集成 四、需求工程五、软件测试5.1 根据程序执行状态…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...