【数据结构与算法】时间复杂度与空间复杂度(上)

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

一.前言

从这篇文章开始,C语言的学习就结束了,接下来将会开启数据结构与算法的学习。

早期,计算机刚被发明出来,内存空间并不是很大,所以不仅追求程序运行时的时间效率,还追求空间效率,但发展到今天,已经不太追求空间效率了,时间效率的追求是不变的。

下面就让我们一起学习时间复杂度和空间复杂度是什么吧~

二.时间复杂度

1.概念

1.时间复杂度是一个函数(注意这不是编程语言里的函数,而是数学意义上的函数)

2.这个函数指的是算法跑的次数的函数,并不是算法运行的时间,因为同一个算法在不同的机器上运行的时间可能是不同的,用算法的运行时间表示时间复杂度是欠妥的;

3.一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。

二.大O的渐进表示法

概念:

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

推导大O阶方法:

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

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

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

需要注意的是算法运行时可能会存在最好情况,最坏情况,平均情况,这个时候我们取最坏情况时的大O;

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

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

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

总结:

1.大O里的数就是函数表达式中对结果影响最大的项,或是最大的量级所在的项

2.如果这个项的系数不是1,那么将它变成1,简单来说,这个项前面的系数得是1

3.如果函数表达式是个常数,不管这个常数多大,都写成O( 1 )

光说不练假把式,让我们通过例题来更好的理解上述所说吧~


三.常见时间复杂度计算举例

例1

1. // 请计算一下Func1中++count语句总共执行了多少次?
2. void Func1(int N)
3. {
4. int count = 0;
5. for (int i = 0; i < N ; ++ i)
6.     {
7. for (int j = 0; j < N ; ++ j)
8.         {
9.             ++count;
10.         }
11.     }
12. for (int k = 0; k < 2 * N ; ++ k)
13.     {
14.         ++count;
15.     }
16. int M = 10;
17. while (M--)
18.     {
19.         ++count;
20.     }
21. printf("%d\n", count);
22. }

不难看出:

Func1 执行的基本操作次数 :

            F(N)=N^2+2^N+10

 N = 10        F(N) = 130

 N = 100      F(N) = 10210

 N = 1000    F(N) = 1002010

显然最大的量级是 N^2

所以时间复杂度为O(N^2)


例2

1. // 计算Func2的时间复杂度?
2. void Func2(int N)
3. {
4. int count = 0;
5. for (int k = 0; k < 2 * N ; ++ k)
6.     {
7.         ++count;
8.     }
9. int M = 10;
10. while (M--)
11.     {
12.         ++count;
13.     }
14. printf("%d\n", count);
15. }

F(N)=2*N+10

影响最大的项为2*N,因为它的系数不是1,所以要变成1,即

时间复杂度:O(N)


例3

1. // 计算Func3的时间复杂度?
2. void Func3(int N, int M)
3. {
4. int count = 0;
5. for (int k = 0; k < M; ++ k)
6.     {
7.         ++count;
8.     }
9. for (int k = 0; k < N ; ++ k)
10.     {
11.         ++count;
12.     }
13. printf("%d\n", count);
14. }

F(N)=M+N

由于并未明确告知M和N的关系,所以时间复杂度:O(M+N)

若M远大于N,则为O(M);

若N远大于M,则为O(N);

若亮着差不多大,则为O(N)或O(M);


例4

1. // 计算Func4的时间复杂度?
2. void Func4(int)
3. {
4. int count = 0;
5. for (int k = 0; k < 100; ++ k)
6.     {
7.         ++count;
8.     }
9. printf("%d\n", count);
10. }

F(N)=100

这是一个常数,所以时间复杂度:O(1)


例5.计算冒泡排序的时间复杂度

不了解冒泡算法请戳我

1. // 计算BubbleSort的时间复杂度?
2. void BubbleSort(int* a, int n)
3. {
4. assert(a);
5. for (size_t end = n; end > 0; --end)
6.     {
7. int exchange = 0;
8. for (size_t i = 1; i < end; ++i)
9.         {
10. if (a[i-1] > a[i])
11.             {
12. Swap(&a[i-1], &a[i]);
13.                 exchange = 1;
14.             }
15.         }
16. if (exchange == 0)
17. break;
18.     }
19. }

最好情况:

原本已排好序,所以进入第二个for循环时不进入if语句,所以exchange==0,直接跳出循环,所以时间复杂度:O(N)

最坏情况:

执行完了所有的循环,所以时间复杂度:O(N^2)

取最坏情况,所以最终的时间复杂度为:O(N^2)

如果没有exchange相关语句,那么最好情况和最坏情况都是O(N^2)


目录
相关文章
|
10天前
|
算法
数据结构:1、时间复杂度
数据结构:1、时间复杂度
16 1
|
2月前
|
机器学习/深度学习 存储 缓存
数据结构从入门到精通——算法的时间复杂度和空间复杂度
算法的时间复杂度和空间复杂度是评估算法性能的两个重要指标。时间复杂度主要关注算法执行过程中所需的时间随输入规模的变化情况,而空间复杂度则关注算法执行过程中所需的最大存储空间或内存空间。
75 0
|
23天前
|
算法 数据处理 C语言
【数据结构与算法】快速排序(详解:快排的Hoare原版,挖坑法和双指针法|避免快排最坏时间复杂度的两种解决方案|小区间优化|非递归的快排)
【数据结构与算法】快速排序(详解:快排的Hoare原版,挖坑法和双指针法|避免快排最坏时间复杂度的两种解决方案|小区间优化|非递归的快排)
|
2月前
|
算法
TOP-K问题和向上调整算法和向下调整算法的时间复杂度问题的分析
TOP-K问题和向上调整算法和向下调整算法的时间复杂度问题的分析
19 1
|
2月前
|
机器学习/深度学习 存储 缓存
数据结构--算法的时间复杂度和空间复杂度
数据结构--算法的时间复杂度和空间复杂度
|
2月前
|
存储 缓存 算法
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
|
2月前
|
存储 算法 Java
Java数据结构与算法-java数据结构与算法(二)
Java数据结构与算法-java数据结构与算法
102 1
|
2月前
|
XML 存储 算法
Java数据结构与算法-java数据结构与算法(五)
Java数据结构与算法-java数据结构与算法
50 0
|
2月前
|
存储 算法 搜索推荐
【C++ 数据结构与算法 一站式备考指南】一文掌握 数据结构与算法课程 知识点(二)
【C++ 数据结构与算法 一站式备考指南】一文掌握 数据结构与算法课程 知识点
94 2
|
2月前
|
存储 算法 C++
【C++ 数据结构与算法 一站式备考指南】一文掌握 数据结构与算法课程 知识点(一)
【C++ 数据结构与算法 一站式备考指南】一文掌握 数据结构与算法课程 知识点
52 2