【数据结构】---时间复杂度与空间复杂度

简介: 【数据结构】---时间复杂度与空间复杂度

image.png

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤

📃个人主页 阿然成长日记 👈点击可跳转

📆 个人专栏: 🔹数据结构与算法🔹C语言进阶

🚩 不能则学,不知则问,耻于问人,决无长进

🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍


1.📉 时间复杂度

📌1.1 时间复杂度的概念

· 时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知 道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法 的时间复杂度

1.2 大O的渐进表示法

O符号(Big O notation):是用于描述函数渐进行为的数学符号。

🔸推导大O阶方法:

1、O(1)用常数1取代运行时间中的所有加法常数。

2、在修改后的运行次数函数中, 只保留最高阶项。

3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。

🔹常见时间复杂度:( 复杂度由小到大)

常数阶 O(1)
线性阶 O(n)
对数阶 O(logn)
nlogn阶 O(nlogn)
平方阶 O(n^2)
立方阶 O(n^3)
指数阶 O(2^n)

🔸大O阶的三种情况:

最坏情况:任意输入规模的最大运行次数(上界)

平均情况:任意输入规模的期望运行次数

最好情况:任意输入规模的最小运行次数(下界)

:我们一般都取最坏的情况作为这个算法的时间复杂度。

🏰空间复杂度

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

·空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。

·空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。

空间复杂度一般都为O(N);

注意:函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。

📃例题分析

1.案例(常数阶)

int fun(int n)
{
  int i = 0;int cnt = 0;
   for( i; i<100;i++)
     {
       cnt++;
      }
  return cnt;
}

此时时间复杂度为O(1),这里的1不是指一次,而是常数次,该循环执行了100次,不管n多大,他都执行100次,所以是O(1)常数阶。

2.案例(线性阶)

分析下面代码复杂度

// 计算Func3的时间复杂度?
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(M+N);

因为我们并不知道M和N谁大,所以我们不能舍弃任何一个。

假如:M无穷大,那么时间复杂度为O(M);反之亦然。

3.案例:(平方阶)

分析下面代码的时间复杂度

int fun(int n)
{
   int cnt = 0;
  for(int i = 0;i < n;i++)
   {
     for(int j = 0; j<n; j++)
      {
        cnt++; 
      }
   }//两层循环,每次循环n次,因此为n*n
  for(int k = 0; k<n; k++)
   {
     ++cnt;
   }//一层循环,循环n次
  for(int l = 0;l<10;l++)
   {
     ++cnt;
   }//一层循环,循环10次
return cnt;
}

我们列出计算时间的复杂度的表达式:n*n +n +10。但是我们能写成O(N*N+N+10吗?我们知道,对于时间复杂度我们不需算出精确的数字,只需要算出这个算法属于什么量级即可,我们又如何知道它属于哪个量级呢?即,我们将字母取无穷大,例如本题中字母为n,n取无穷大,而十对于n取无穷大后没有影响,因此10可以舍去,原表达式化为nn+n,再转化为n(n+1),由于n为无穷大,因此-1也是没有影响的,原式就变成了O(N*N)=O(N^2)

📌 在这里我们使用大O渐近表示法,只是一种量级的估算,而不是准确的值。

4.案例(平方阶)

分析冒泡排序的时间复杂度

void bubblesort(int* a,int n)
{
   assert(a);
for(int end = n; end>0; end--)
    {
      int exchange = 0;
       for(int i = 1; i<end; i++)
           {
              if(a[i-1]>a[i])
              {
                swap(&a[i],&a[i-1]);
                 exchange = 1;
               }
            }
       if(exchange==0)
           break;
     }
}

在这个冒泡排序中,我们需要将无序数组转化为有序数组的一种算法,它并不是简单的双层嵌套循环,很容易想到它的循环次数是一个等差数列,第一次循环n-1次,第二次n-2次…一直到1.因此为n-1+n-2+n-3…+1 =·n*(n-1)/2,使用大O表示,去掉影响不大的项,简化为: 时间复杂度为O(N*N)。

5.案例(对数阶)

二分查找

int binary(int n, int a[], int k) 
{
  int left = 0, right = n - 1;
  while(l <= r) {
    mid = (l + r)/2;
    if(a[mid] == k) 
        return mid;
    else if(a[mid] < k)
      right = mid + 1;
    else
      left = mid + 1;
  }
  return -1;
}

eft和right指数组最左边和最右边的下标.每次将这个数组砍一半,求出mid中间下标. 由于是升序排列,如果中间下标代表的数大于给定的数k,那么k必定在中间下标的左边. 那么就将mid+1的值赋给right,反之则将mid+1的值赋给left,每次将数组砍一半直到找到数k为止.

也就是每次除二。2^n=N -> n=logN;

6.案例(递归调用)

斐波那契函数

long long Fac(size_t N)
{
 if(N == 0)
 return 1;
 return Fac(N-1)*N;

推到知道,这个函数会不停的向下调用,呈金字塔型,虽然运算量非常大,但是我们在算时间复杂度时要关注代码的思想,而不是看它的次数等。 递归函数的时间复杂度是多次用的次数的累加。

空间复杂度:根据调用的次数,每次都会占用栈上的空间,所以间复杂度为O(N);

❗️总结:

不管是算时间复杂度,还是空间复杂度。我们都要根据代码的思想,探求程序运行的过程,来思考复杂度。不能片面的根据数量,次数的多少来算。

相关文章
|
4月前
|
算法 搜索推荐 程序员
数据结构中时间复杂度的介绍
冒泡排序是通过重复遍历数组,比较并交换相邻元素来排序数组的。因为它包含两层嵌套循环,每层循环的最大迭代次数近似于n,所以时间复杂度是O(n²)。 通过上述分析,我们可以看到不同代码结构对算法性能有着显著的影响。在设计数据结构和算法时,理解并计算时间复杂度是非常重要的,它帮助程序员选择或优化算法,以处理更大的数据集或提高程序的运行速度。
27 2
|
4月前
|
存储 算法 C语言
数据结构中的空间复杂度
优化空间复杂度对于提升程序性能和资源利用率至关重要,特别是在资源受限的环境(如嵌入式系统和移动设备)中。高效的数据结构和算法设计可以显著提升程序的执行效率和可扩展性。 综上所述,理解和优化空间复杂度是设计高效数据结构和算法的关键。通过分析常见数据结构的空间复杂度,并结合实际代码示例,我们可以更好地理解这一重要概念,并在实际编程中应用这些知识。希望本文能帮助你更好地掌握空间复杂度及其在数据结构中的应用。
34 2
|
2月前
|
存储 算法
【数据结构】——时间复杂度与空间复杂度
【数据结构】——时间复杂度与空间复杂度
|
4月前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
4月前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-1
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
4月前
|
算法
数据结构和算法学习记录——时间复杂度、空间复杂度相关练习题
数据结构和算法学习记录——时间复杂度、空间复杂度相关练习题
31 2
|
4月前
|
机器学习/深度学习 算法
数据结构入门 时间 空间复杂度解析
数据结构入门 时间 空间复杂度解析
28 0
|
4月前
|
存储 算法 C语言
数据结构和算法——堆排序(选择排序、思路图解、代码、时间复杂度、堆排序及代码)
数据结构和算法——堆排序(选择排序、思路图解、代码、时间复杂度、堆排序及代码)
30 0
|
4月前
|
算法 Shell C语言
数据结构与算法——希尔排序(引例、希尔增量序列、原始希尔排序、代码、时间复杂度、Hibbard增量序列、Sedgewick增量序列)
数据结构与算法——希尔排序(引例、希尔增量序列、原始希尔排序、代码、时间复杂度、Hibbard增量序列、Sedgewick增量序列)
43 0
|
4月前
|
人工智能 算法 C语言
数据结构与算法——简单排序-冒泡排序、插入排序,时间复杂度下界(图示、代码、时间复杂度、定理)
数据结构与算法——简单排序-冒泡排序、插入排序,时间复杂度下界(图示、代码、时间复杂度、定理)
31 0