算法复杂度<数据结构 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)


常见复杂度对比:

相关推荐
爱吃生蚝的于勒32 分钟前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~35 分钟前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
脉牛杂德1 小时前
多项式加法——C语言
数据结构·c++·算法
一直学习永不止步2 小时前
LeetCode题练习与总结:赎金信--383
java·数据结构·算法·leetcode·字符串·哈希表·计数
wheeldown10 小时前
【数据结构】选择排序
数据结构·算法·排序算法
躺不平的理查德14 小时前
数据结构-链表【chapter1】【c语言版】
c语言·开发语言·数据结构·链表·visual studio
阿洵Rain14 小时前
【C++】哈希
数据结构·c++·算法·list·哈希算法
Leo.yuan14 小时前
39页PDF | 华为数据架构建设交流材料(限免下载)
数据结构·华为
半夜不咋不困14 小时前
单链表OJ题(3):合并两个有序链表、链表分割、链表的回文结构
数据结构·链表
忘梓.15 小时前
排序的秘密(1)——排序简介以及插入排序
数据结构·c++·算法·排序算法