2.复杂度分析(下)
最好、最坏情况时间复杂度
1 // n 表示数组 array 的长度 2 int find(int[] array, int n, int x) { 3 int i = 0; 4 int pos = -1; 5 for (; i < n; ++i) { 6 if (array[i] == x) 7 pos = i; 8 } 9 return pos; 10 }
时间复杂度为O(n)
代码优化:
1 // n 表示数组 array 的长度 2 int find(int[] array, int n, int x) { 3 int i = 0; 4 int pos = -1; 5 for (; i < n; ++i) { 6 if (array[i] == x) { 7 pos = i; 8 break; 9 } 10 } 11 return pos; 12 }
最好情况时间复杂度就是,在最理想的情况下,执行这段代码的时间复杂度
最坏情况时间复杂度就是,在最糟糕的情况下,执行这段代码的时间复杂度
平均情况时间复杂度
上例:
n+1种情况:在数组0~n-1位置,不在数组
因此平均遍历的元素个数平均值为:
省略系数、低阶、常量、得到:O(n)
但上述推导中忽略了每种情况的概率问题,假设在数组p 1= 1/2,不在p 2= 1/2,每个位置出现查找的数据p = p1 * 1/n = 1/2n
这个值便是概率论中的加权平均值,也叫期望值,因此平均时间复杂度全称为加权平均复杂度或者期望时间复杂度
省略系数、低阶、常量、仍得到:O(n)
一般情况下,只使用一个时间复杂度,只有不同情况下,有量级差距,才会有以上这三种来区分
均摊时间复杂度(不经常用的)
1 // array 表示一个长度为 n 的数组 2 // 代码中的 array.length 就等于 n 3 int[] array = new int[n]; 4 int count = 0; 5 6 void insert(int val) { 7 if (count == array.length) { 8 int sum = 0; 9 for (int i = 0; i < array.length; ++i) { 10 sum = sum + array[i]; 11 } 12 array[0] = sum; 13 count = 1; 14 } 15 16 array[count] = val; 17 ++count; 18 }
先用三种时间复杂度来分析
最理想,数组有空闲,为O(1)
最糟糕,count = array.length,为O(n)
平均的,假设array.length = n,count共有n+1种情况,可插入的n种,p1 = 1/(n+1),
无空间插入的1种,p2 = 1/(n+1),平均复杂度为:
对比上面的find()
1. insert()大多数情况为O(1),个别复杂度才高,为O(n),而find()则极端情况下才为O(1);
2. Insert()O(1)和O(n)的时间复杂度插入频率很有规律,有一定前后时序关系,一般先1个O(n),后n-1O(1),循环往复。
对于这种情况,可以将每一次的O(1)操作的时间分摊到,n-1次O(n)上,这样这样的连续操作的均摊时间复杂度就是O(1)
可以将均摊时间复杂度理解为一种特殊的平均时间复杂度
课后思考
求add()的复杂度
1 // 全局变量,大小为 10 的数组 array,长度 len,下标 i。 2 int array[] = new int[10]; 3 int len = 10; 4 int i = 0; 5 6 // 往数组中添加一个元素 7 void add(int element) { 8 if (i >= len) { // 数组空间不够了 9 // 重新申请一个 2 倍大小的数组空间 10 int new_array[] = new int[len*2]; 11 // 把原来 array 数组中的数据依次 copy 到 new_array 12 for (int j = 0; j < len; ++j) { 13 new_array[j] = array[j]; 14 } 15 // new_array 复制给 array,array 现在大小就是 2 倍 len 了 16 array = new_array; 17 len = 2 * len; 18 } 19 // 将 element 放到下标为 i 的位置,下标 i 加一 20 array[i] = element; 21 ++i; 22 }
·········································不准偷看线················································
最好是O(1),最差是O(n), 均摊是O(1)