一:⼤O的渐进表⽰法
我们计算时间复杂度时,计算的也不是程序的精确的执⾏次数,精确执⾏次数计算起来还是很 ⿇烦的(不同的⼀句程序代码,编译出的指令条数都是不⼀样的),计算出精确的执⾏次数意义也不⼤, 只需要计算程序能代表增⻓量级的⼤概执⾏次数,复杂度的表⽰通常使⽤⼤O的渐进表⽰法。
1. 时间复杂度函数式T(N)中,只保留最⾼阶项,去掉那些低阶项,因为当N不断变⼤时,
低阶项对结果影响越来越⼩,当N⽆穷⼤时,就可以忽略不计了。
2. 如果最⾼阶项存在且不是1,则去除这个项⽬的常数系数,因为当N不断变⼤,这个系数
对结果影响越来越⼩,当N⽆穷⼤时,就可以忽略不计了。
3. T(N)中如果没有N相关的项⽬,只有常数项,⽤常数1取代所有加法常数。
(1):
// 计算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;
}
strchr执⾏的基本操作次数:
1)若要查找的字符在字符串第⼀个位置,则:T (N) = 1
2)若要查找的字符在字符串最后的⼀个位置,则:T (N) = N
3)若要查找的字符在字符串中间位置,则:T (N) = N/2
因此:strchr的时间复杂度分为:最好情况:O(1) 最坏情况:O(N) 平均情况:O(N)
(2):
// 计算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; }
}
1)若数组有序,则:T (N) = N
2)若数组有序且为降序,则:T (N) = (N ∗ (N + 1))/2
3)若要查找的字符在字符串中间位置,则:因此:BubbleSort的时间复杂度取最差情况为:O(N )
(3):
void func5(int n)
{int cnt = 1;while (cnt < n){cnt *= 2;}
}
当n=2时,执⾏次数为1
当n=4时,执⾏次数为2
当n=16时,执⾏次数为4
假设执⾏次数为x ,则2^x=n
因此执⾏次数:x = log n
因此:func5的时间复杂度取最差情况为:O(logn)