算法复杂度<数据结构 C版>

什么是算法复杂度?

简单来说算法复杂度是用来衡量一个算法的优劣的,一个程序在运行时,对运行时间和运行空间有要求,即时间复杂度和空间复杂度。


目录

什么是算法复杂度?

大O的渐近表达式

时间复杂度示例

空间复杂度示例

常见复杂度对比:


大O的渐近表达式

时间复杂度,我们常常使用大O的渐近表示法

推导大O阶的规则:

●时间复杂度函数式T(N)中,只保留高阶项,去掉那些低阶项。

(因为当N不断变大时,低阶项对结果的影响越来越小,当N无穷大时,就可以忽略不计了)

●如果最高阶项存在且不是1,则去除这个项目的常数系数。

(因为当N不断变大,这个系数对结果的影响不断变小,当N无穷大时,其就可以忽略不计了)

●T(N)如果没有N相关的项目,只有常数项,那么就用常数1替代所有加法。


时间复杂度示例

cpp 复制代码
// 计算Func2的时间复杂度? 
void Func2(int N) 
{ 
     int count = 0; //1次
     for (int k = 0; k < 2 * N ; ++ k) 
     { 
         ++count; //2*N次
     } 
     int M = 10; 
     while (M--) 
     { 
         ++count; //10次
     } 
     printf("%d\n", count); 
}

得:T(N)=1+2*N+10

由第一条和第二条规则得到时间复杂度O(N).


cpp 复制代码
// 计算Func3的时间复杂度? 
void Func3(int N, int M) 
{ 
     int count = 0; 
     for (int k = 0; k < M; ++ k) //M次
     { 
         ++count; 
     } 
     for (int k = 0; k < N ; ++ k) //N次
     { 
         ++count; 
     } 
 printf("%d\n", count); 
}

得:T(N)=M+N

由第一条规则或第二条规则得到时间复杂度O(N).

(因为使用N代表其中增长速度快的哪一项,则忽略掉增长速度慢的那一项,当M和N增长速度一样时为2N,则忽略系数)


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

得:T(N)=100

由第三条规则得到时间复杂度O(1).


cpp 复制代码
// 计算strchr的时间复杂度? 
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;
}

①最好情况

str的第一个字符就等于character,得:T(N)=1,则时间复杂度为O(1).

②平均情况

要查找的字符在str的中间,得:T(N)=N/2,则时间复杂度为O(N).

③最差情况

要查找字符在str的末尾,得:T(N)=N,则时间复杂度为O(N).

一般的我们取最差情况来表示算法的时间复杂度


★某些算法存在分情况的时间复杂度

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

●平均情况:任意输入规模的平均次数.

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

cpp 复制代码
// 计算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; 
 } 
}

通过上面的分析,我们可尝试求出三种情况:

最坏情况:倒序,O(N^2)

平均情况:平均情况,O(N^2)

最好情况:有序,O(N)


cpp 复制代码
void func5(int n)
{
     int cnt = 1;
     while (cnt < n)
     {
         cnt *= 2;
     }
}

分析得T(N)=log2n,即O(logn).


cpp 复制代码
// 计算阶乘递归Fac的时间复杂度? 
long long Fac(size_t N) 
{ 
     if(0 == N)
        return 1; 
 return Fac(N-1)*N; 
}

时间复杂度:O(N).


空间复杂度示例

空间复杂度的表示也使用大O表达式。

cpp 复制代码
// 计算BubbleSort的时间复杂度? 
void BubbleSort(int* a, int n) 
{ 
     assert(a); //1次
     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; 
     } 
}

空间复杂度:O(1).


cpp 复制代码
// 计算阶乘递归Fac的空间复杂度? 
long long Fac(size_t N) 
{ 
 if(N == 0) 
     return 1; 
 
 return Fac(N-1)*N; 
}

开辟了N个函数栈帧,空间复杂度为O(N)


常见复杂度对比:

相关推荐
richard_yuu15 小时前
数据结构|二叉树高阶进阶-经典算法
数据结构·c++·算法
不知名的忻15 小时前
Dijkstra算法(朴素版&堆优化版)
java·数据结构·算法··dijkstra算法
YL2004042617 小时前
027合并两个有序链表
java·数据结构·算法·链表
Zephyr_017 小时前
java数据结构
java·数据结构
xieliyu.18 小时前
Java手搓二叉树:基础遍历与核心操作全解析
java·开发语言·数据结构·学习
期待のcode18 小时前
Redis数据类型
运维·数据结构·redis
博界IT精灵19 小时前
图的遍历(哈喜老师)
数据结构·考研·算法·深度优先
所以遗憾是什么呢?19 小时前
【题解】Codeforces Round 1097 (Div. 2, Based on Zhili Cup 2026) (致理杯) ABCDEF
数据结构·算法·acm·codeforces·icpc·ccpc·xcpc
Lazionr20 小时前
【栈与队列经典OJ】
c语言·数据结构
夏日听雨眠20 小时前
数据结构(哈希函数)
数据结构·算法·哈希算法