当前位置: 首页 > news >正文

算法复杂度,咕咕咕

1.数据结构与算法

数据结构是计算机存储,组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。可以理解为形状不同的容器。

算法是定义好的计算过程,取输入值,经过一系列计算方法变成输出值。

(推荐《数据结构》c或c++版,《算法导论》托马斯,《大话数据结构》程杰)

2.算法效率

复杂度:算法在编写成可执行程序后,运行时要耗费时间与空间资源,即时间复杂度,空间复杂度

时间复杂度主要衡量一个算法的运行快慢,空间复杂度主要衡量算法运行所需的额外空间。

但是在现在计算机的存储容量不断变大,空间复杂度不需要重度关注

3.时间复杂度

描述算法的运行时间,衡量程序的时间效率。(函数式T(N))

(为什么不去计算程序的运行时间?程序运行时间与编译环境与配置都有关系,不单单是算法。

并且这样的话时间只能再程序写好后测试,而不能在写完前理论计算评估)

T(N)计算了程序的执行次数。算法程序在被编译后生成二进制指令,程序运行就是CPU执行这些编译好的指令。每句指令执行时间基本一样,那么执行次数和运行时间就正相关,脱离具体的编译运行环境,可以代表程序时间效率的优劣。

void func1(int n)
{
int count=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
++count;
}
}
for(int k=0;k<2*n;k++)
{
++count;
int m=10;
while(m--)
{
++count;
}
}T(N)=N^2+2*N+10,对结果影响最大的是n^2,O(n^2)

我们实际计算时间复杂度时,计算的也不是程序精确的执行次数,只是计算增长量级,用O的渐进表示法

3.O的渐进表示法

T(N)只保留最高阶项,去掉低阶项。如果最高项存在且不是1,则去掉项的常数系数。如果没有N相关的项目,只有常数项,用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",count);
}
T(N)=2N+10;
O(N)
void func3(int n)
{
int count=0;
for(int k=0;k<n;k++)
{
++count;
}
for(int k=0;k<n;k++)
{
++count;
}
printf("%d",count);
}
T(N)=N+M;
O(N)
void func4(int n)
{
int count=0;
for(int k=0;k<100;k++)
{
++count;
}
printf("%d",count);
}
T(N)=100;
O(1)
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)=1
在最后一个位置,T(N)=N
在中间T(N)=N/2
最好情况O(1),最坏情况O(N),平均情况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;
}
}
}如果数组有序,T(N)=N
有序且为降序,T(N)=N*(N+1)/2
取上界,O(N^2)
void func5(int n)
{
int cnt=1;
while(cnt<n)
{
cnt*=2;
}
}
执行次数x,2^x=n
x=logn
O(logn)
long long Fac(size_t n)
{
if(0==n) return 1;
return Fac(n-1)*n;
}
调用一次Fac函数的时间复杂度O(1),总共调用n次递归函数,O(n)

4.空间复杂度

是一个算法在运行过程中需要额外临时开辟的空间,不是程序要占用多少bytes的空间,算的是变量的个数,用O渐进表示法,函数运行时所需要的栈空间(存储参数,局部变量,一些寄存器信息)在编译期间已经确定,空间复杂度主要通过函数运行时显式申请的额外空间确定

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;
}
}
}
bubblesort额外申请的空间有exchange等有限个局部变量,使用了常数个额外空间,O(1)
long long Fac(size_t n)
{
if(n==0)
return 1;
return Fac(n-1)*n;
}
Fac递归调用了n次,额外开辟了n个函数栈帧,每个栈帧使用了常数个空间,O(n)

5.常见复杂度对比

6.例题

给定一个整形数组nums,把数组中元素向右轮转k个位置,k为非负数

时间复杂度O(n^2)
void rotate(int *num,int numsize,int k)
{
while(k--)
{
int end=num[numsize-1];
for(int i=numsize-1;i>0;i++)
{
num[i]=num[i-1];
}
num[0]=end;
}
}
循环k次把数组所有元素向后移动一位
空间复杂度O(n)
申请新数组,把后k个数据放进新数组,再把剩下的设局挪到数组中
void rotate(int* num,int numsize,int k)
{
int newarr[numsize];
for(int i=0;i<numsize;++i)
{
newarr[(i+k)%numsize]=num[i];
}
for(int i=0;i<numsize;++i)
{
num[i]=newarr[i];
}
}
空间复杂度O(1)
前n-k个逆置
后k个逆置
整个逆置
void reverse(int* num,int begin,int end)
{
while(begin<end)
{
int tmp=num[begin];
num[begin]=num[end];
num[end]=tmp;
begin++;
end--;
}
}
void rotate(int* num,int numsize,int k)
{
k=k%numsize;
reverse(num,0,numsize-k-1);
reverse(num,numsize-k,numsize-1);
reverse(num,0,numsize-1);
}/*
void rotate(vector<int>& nums, int k) {k%=nums.size();reverse(nums.begin(),nums.begin()+nums.size()-k);reverse(nums.begin()+nums.size()-k,nums.end());reverse(nums.begin(),nums.end());}
*/

http://www.xdnf.cn/news/890605.html

相关文章:

  • 晨读笔记 6-5 (主题:打造15分钟就业服务圈)
  • SpringBoot+Mysql实现的停车场收费小程序系统+文档
  • GPU显存的作用和如何选择
  • 带有输入的CDS和程序调用
  • 极限c++模拟卷
  • 使用 Run:ai Model Streamer 实现模型的高效加载
  • JAVASCRIPT 简化版数据库--智能编程——仙盟创梦IDE
  • AI Agent时代里的SAAS是伪命题还是突破点?
  • spring4第7-8课-AOP的5种通知类型+切点定义详解+执行顺序
  • 如何配置Git LFS?
  • Next打包导出静态文件(纯前端),不要服务器端(node), 隐藏左下角调试模式(“next“: “^15.3.3“,)
  • 力扣刷题Day 71:搜索旋转排序数组(33)
  • dvwa13——CSP Bypass
  • ubuntu 端口复用
  • Ubantu-Docker配置最新镜像源250605
  • PHP 打印扩展开发:从易联云到小鹅通的多驱动集成实践
  • 打造高效多模态RAG系统:原理与评测方法详解
  • Cad 反应器 cad c#二次开发
  • 【复杂指令遵循 Benchmark】论文分享:CodeIF-Bench
  • 软件开发中的“需求镀金”现象如何避免?
  • 大屏缩放视频比例适配记录
  • Canvas的使用
  • 计算机网络安全问答数据集(1788条) ,AI智能体知识库收集! AI大模型训练数据!
  • AI04A AI模块,16通道,TC / mV
  • Python中的self参数介绍
  • [GESP202412 五级] 奇妙数字 题解
  • 核心机制:延时应答,捎带应答,面向字节流
  • Shopify 主题开发:移动端菜单响应式设计要点
  • jdbc查询mysql数据库时,出现id顺序错误的情况
  • Android基础回顾】六:安卓显示机制Surface 、 SurfaceFlinger、Choreographer