数据结构之一:复杂度

ops/2024/11/26 16:59:59/

相关代码:SData/test_22/main.c · Hera_Yc/bit_C_学习 - 码云 - 开源中国

数据结构:在内存当中存储、组织数据的方式。(顺序表、链表、栈、队列、树等)。

算法:与数据结构配合使用,是对数据的处理。(查找、排序、二分查找、动态规划等)。

复杂度:用来分析算法的性能,算法的性能分为时间开销和空间占用两个部分。

        现代计算机,对空间复杂度的要求很低了。根据摩尔定律,现代计算机的内存已经是相当大的,对于几个字节的额外开销,这些空间复杂度可以忽略不计了。(1GB大约可以定义2千5百万个int)。


时间复杂度

        算法的时间复杂度是一个函数,它描述了该算法的运行时间。从理论上讲,执行一段算法所消耗的时间是不可计算的。因此:

时间复杂度:描述算法中基本操作的执行次数

大O渐进表示法

void Func(int N)
{int count = 0;int i = 0;int j = 0;for (i=0; i < N; i++){for (j=0; j < N; j++){count++;}}int M = 10;while (M--){count++;}printf("%d\n", count);return;
}
//F(N)=N*N+2*N+10
//用大O的渐进表示法表示
//O(N)=N*N

        实际计算中,我们并不一定要精确的计算,只需要大致的执行次数,因此我们这里使用大O渐进表示法

推导大O阶方法:

  1. 用常数1取代运行时间中的所有加法常数。
  2. 在修改后的运行函数中,只保留最高项。
  3. 如果最高项存在且不是1,则去除与这个项目相乘的常数,得到的结果就是大O阶。
  4. 可以根据算法的名称推算时间复杂度。(从算法思想上计算)。

对于一些算法,它们的时间复杂度不是固定的,存在最好和最坏的两种情况:

  • 最坏情况:任意输入规模的最运行次数(上界)。
  • 平均情况:任意输入规模的期望运行次数。
  • 最好情况:任意输入规模的最运行次数(下界)。

实例

1、O(M+N)

int Func2(int N, int M)
{int i = 0;int count = 0;for (i = 0; i < N; i++){count++;}for (i = 0; i < M; i++){count++;}return 0;
}
//O(M+N)

2、 O(1)

void Func3(int N)
{int k = 0;int count = 0;for (k = 0; k < 100; k++){count++;}
}
O(1)

 3、冒泡排序的时间复杂度

//冒泡排序
//时间复杂度O(N^2)
//最好情况是O(N)
#include <assert.h>
void BubbleSort(int a[],int n)
{assert(a);size_t end = 0;for (end = n; end > 0; end--){int exchange = 0;size_t i = 1;for (i = 1; i < end; i++){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = 1;}}if (exchange = 0)break;}}

 4、二分查找的时间复杂度

int BinSearch(int* arr,int sz,int oj)
{int left = 0;int right = sz - 1;int mid = 0;while (left < right){mid = left + (right - left) / 2;if (arr[mid] < oj){left = mid + 1;}if (arr[mid] > oj){right = mid - 1;}if (arr[mid] == oj){return arr[mid];}}return -1;
}

 根据二分查找的算法逻辑来推算时间复杂度:

  • 最好的情况:一次找到,O(1)
  • 最坏的情况:最后一次找到:log2(N)
  • 时间复杂度:O(log2(N))

5、递归函数(初步认识、后面补充)

//求阶乘
//O(N)
//递归算法如何计算:递归次数*每次递归函数的次数
long long Fac(size_t N)
{return N < 2 ? N : Fac(N - 1) * N;
}

6、斐波那契()


空间复杂度

空间复杂度:计算的是定义的变量个数,包括调用其他函数的栈帧

空间复杂度的计算与时间复杂度类似:

  1. 用常数1取代运行时间中的所有加法常数。
  2. 每定义一个变量,空间复杂度+1。
  3. 每调用一次其他函数,开辟一个新的栈帧,有额外的空间复杂度。
  4. 函数的形式参数也算空间复杂度的一部分。

时间复杂度不计算时间,计算的是大概的运算次数。

空间复杂度不计算空间,计算的是大概定义的变量个数。


http://www.ppmy.cn/ops/136874.html

相关文章

进程间通信5:信号

引入 我们之前学习了信号量&#xff0c;信号量和信号可不是一个东西&#xff0c;不能混淆。 信号是什么以及一些基础概念 信号是一种让进程给其他进程发送异步消息的方式 信号是随时产生的&#xff0c;无法预测信号可以临时保存下来&#xff0c;之后再处理信号是异步发送的…

重构代码之将引用类型更改为值类型

将引用类型更改为值类型的目标是将引用类型转换为值类型&#xff0c;通常是为了简化代码&#xff0c;减少副作用&#xff0c;提高代码的可理解性和可维护性。这个重构技术适用于那些引用类型在某些情况下表现得像值类型的场景&#xff0c;尤其是当引用类型不需要共享状态时。通…

RLC串联谐振,品质因数的影响

串联谐振 电路谐振是正弦稳态电路的一种特定的工作状态&#xff0c;通常发生在电感L&#xff0c;电容C和电阻R构成的电路。当高频信号通过电感或者电容的时候会产生感抗或者容抗&#xff0c;电感的感抗随着频率的增加而增加&#xff0c;电容的容抗随着频率的增加而降低。 对于串…

Excel的图表使用和导出准备

目的 导出Excel图表是很多软件要求的功能之一&#xff0c;那如何导出Excel图表呢&#xff1f;或者说如何使用Excel图表。 一种方法是软件生成图片&#xff0c;然后把图片写到Excel上&#xff0c;这种方式&#xff0c;因为格式种种原因&#xff0c;导出的图片不漂亮&#xff0c…

随手记:鼠标触顶方法

// 鼠标触顶方法 scrollMethod() { window.onscroll () > { let t document.documentElement.scrollTop || document.body.scrollTop; if(t > 10) { this.positionStyle.top 0px; }else{ this.positionStyle.top 128px; } } },

【大模型-智能体】AutoGen Studio测试和导出工作流程

1. 测试工作流程 AutoGen Studio允许用户针对任务交互式地测试工作流程&#xff0c;并审查由此产生的成果物&#xff08;如图像、代码和文档&#xff09;。此外用户还可以查看Agent工作流程在处理任务时的“内心独白”&#xff0c;并查看诸如运行成本&#xff08;如回合数、令牌…

大语言模型提示词工程学习--写小说系列(文心一言豆包通义千问):2~确定核心谜团

在上一篇 大语言模型提示词工程学习--写小说系列&#xff08;文心一言&豆包&通义千问&#xff09;&#xff1a;1~创作前的准备工作 中&#xff0c;我们已经使用AI确定了进行小说创作的8个步骤&#xff0c;在接下来的章节中&#xff0c;我们将一步一步按照AI给出的步骤&…

环形缓冲区

什么是环形缓冲区 环形缓冲区,也称为循环缓冲区或环形队列,是一种特殊的FIFO(先进先出)数据结构。它使用一块固定大小的内存空间来缓存数据,并通过两个指针(读指针和写指针)来管理数据的读写。当任意一个指针到达缓冲区末尾时,会自动回绕到缓冲区开头,形成一个"环"。…