算法的时间复杂度

简介: 算法的时间复杂度

⭐算法效率

如何衡量一个算法的好坏?

算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源 。因此衡量一个算法的好坏,一般是从时间空间两个维度来衡量的,即时间复杂度空间复杂度

⭐时间复杂度

一个程序的运行,依赖于其本身的算法设计以及不同的机器性能。单纯地只是从计算其运算时间的角度来评估一个算法是不合理的。

因此引进了时间复杂度

🌟时间复杂度

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

在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度,更关注一个算法的时间复杂度。

🐟时间复杂度的概念

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

🐳例1

// 请计算一下Func1中++count语句总共执行了多少次?
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;
    }
    printf("%d\n", count);
}

Func1执行的基本操作次数

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

但实际上当N非常大时,最高数量级的N^2对F(N)会起到决定性影响。

并且在实际中,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法

🐟大O的渐进表示法

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

推导大O阶方法:
1、用常数1取代运行时间中的所有加法常数
2、在修改后的运行次数函数中,只保留最高阶项

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

🐳 例2

// 计算Func2的时间复杂度?
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);
}

具体的执行次数F(N)=2N+10

我们只需要抓大头,for循环这条语句是最主要的。

因此Func2的时间复杂度为O(N)

🐳例3

// 计算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);
}

Func3函数中,M和N是两个未知数。

当M>>N时,算法的时间复杂度为:O(M)

当N>>M时,算法的时间复杂度为: O(N)

当M=N时,算法的时间复杂度为O(M)或者O(N)

但由于我们不清楚M和N的具体关系,因此这个算法的时间复杂度为:O(M+N)更准确。

🐳例4

// 计算Func4的时间复杂度?
void Func4(int N)
{
    int count = 0;
    for (int k = 0; k < 100; ++ k)
    {
        ++count;
    }
    printf("%d\n", count);
}

Func4是可以清楚地知道for语句语句会执行100次,因此这个算法的时间复杂度为O(1)

🐳例5

// 计算Func5的时间复杂度?
void Func4(int N)
{
    int count = 0;
    for (int k = 0; k < 1000000; ++ k)
    {
        ++count;
    }
    printf("%d\n", count);
}

如果这里换成1000,000实际上算法的时间复杂度还是O(1)。

这主要依赖于CPU的强大。CPU的运算速度是十分快的。

这是由于此,对于CPU而言,运行100和1000,1000000 语句,其时间都是一样的。

🐳例6

// 计算strchr的时间复杂度?
const char * strchr ( const char * str, int character );

这个库函数表示,在字符串s中查找字符c,返回字符c第一次在字符s中出现的位置,如果未找到字符c,则返回NULL。

这个需要分情况讨论。

比如说,调用这个函数,并传递参数,字符串"hello,world"。

最好的情况是,查找的字符,我们传递的是字符"h",那么这样就只进行了1次查找。

最坏的情况是,查找的字符,我们传递的参数是"d"那么这样就遍历了一次字符数组11次才查找到。或者我们传递的参数是"a",遍历了数组,没有查找到。

平均情况是,11/2=5次

在这种情况中我们关注的是算法最坏的情况。

另外有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数

最好情况:任意输入规模的最小运行次数(下界) 例如:在一个长度为N数组中搜索一个数据x
在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)

🐳例7

// 计算BubbleSort的时间复杂度?
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;
    }
}

这个算法是冒泡排序。

冒泡排序,是两个相邻元素进行比较,交换;重复这个过程,将最大(重)的沉下去。重复上述,将第二大再沉下去。…

最好情况是,无需进行交换。

最坏情况是,假如有n个数。

第一次交换为n-1次。

第二次交换为n-2次。

第三次交换为n-3次。

第n-1次交换为1次

所以总次数为

为(n-1)+(n-2)+(n-3)+…+1=[(n-1)+1]*(n-1)/2=n(n-1)/2次。

故冒泡算法的时间复杂度为

O(N^2)

相关文章
|
3月前
|
机器学习/深度学习 缓存 算法
Python算法设计中的时间复杂度与空间复杂度,你真的理解对了吗?
【10月更文挑战第4天】在Python编程中,算法的设计与优化至关重要,尤其在数据处理、科学计算及机器学习领域。本文探讨了评估算法性能的核心指标——时间复杂度和空间复杂度。通过详细解释两者的概念,并提供快速排序和字符串反转的示例代码,帮助读者深入理解这些概念。同时,文章还讨论了如何在实际应用中平衡时间和空间复杂度,以实现最优性能。
86 6
|
5月前
|
机器学习/深度学习 算法 程序员
读《趣学算法》:重开算法之门,时间复杂度与空间复杂度
本文是作者阅读《趣学算法》后的笔记,介绍了算法复杂度的基本概念,包括时间复杂度和空间复杂度的不同阶表示,并通过具体例子展示了如何计算和理解算法的效率。
73 2
读《趣学算法》:重开算法之门,时间复杂度与空间复杂度
|
3月前
|
搜索推荐 算法
插入排序算法的平均时间复杂度解析
【10月更文挑战第12天】 插入排序是一种简单直观的排序算法,通过不断将未排序元素插入到已排序部分的合适位置来完成排序。其平均时间复杂度为$O(n^2)$,适用于小规模或部分有序的数据。尽管效率不高,但在特定场景下仍具优势。
|
6月前
|
机器学习/深度学习 存储 算法
颠覆认知!Python算法设计中的时间复杂度与空间复杂度,你真的理解对了吗?
【7月更文挑战第22天】在Python算法设计中,时间与空间复杂度是评估算法效能的核心。时间复杂度不仅限于大O表示法,还涵盖平均与最坏情况分析。空间复杂度虽关注额外存储,但也反映内存效率。平衡二者需视场景而定,如利用原地算法减少内存消耗,或牺牲空间加速执行。算法优化技巧,如分治与动态规划,助你在资源与速度间找寻最优解,从而高效应对大数据挑战。
58 3
|
3月前
|
机器学习/深度学习 存储 缓存
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
文章主要介绍了排序算法的分类、时间复杂度的概念和计算方法,以及常见的时间复杂度级别,并简单提及了空间复杂度。
50 1
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
|
3月前
|
存储 算法
算法的时间复杂度和空间复杂度
本文详细讨论了算法的时间复杂度和空间复杂度,包括它们的概念、计算方法和常见复杂度的对比,并通过多个实例解释了如何计算算法的时间和空间复杂度。
205 0
算法的时间复杂度和空间复杂度
|
4月前
|
算法 Python
震惊!Python 算法设计背后,时间复杂度与空间复杂度的惊天秘密大起底!
在 Python 算法设计中,理解并巧妙运用时间复杂度和空间复杂度的知识,是实现高效、优雅代码的必经之路。通过不断地实践和优化,我们能够在这两个因素之间找到最佳的平衡点,创造出性能卓越的程序。
45 4
|
3月前
|
算法 C语言
深入理解算法效率:时间复杂度与空间复杂度
深入理解算法效率:时间复杂度与空间复杂度
|
5月前
|
机器学习/深度学习 存储 算法
算法时间复杂度分析
这篇文章讲解了如何分析算法的时间复杂度,包括关注循环执行次数最多的代码段、总复杂度的确定、嵌套代码复杂度的计算方法,并提供了大O阶的推导步骤和常见时间复杂度的列表,同时还介绍了空间复杂度的概念及其重要性。
|
5月前
|
搜索推荐
九大排序算法时间复杂度、空间复杂度、稳定性
九大排序算法的时间复杂度、空间复杂度和稳定性,提供了对各种排序方法效率和特性的比较分析。
209 1

热门文章

最新文章