一、常数操作:
常见固定时间的操作
1、常见算术运算+、-、*、/、
2、位运算 >>、>>>、 << 、 | 、 & 、^等
3、赋值、比较、自增、自减
4、数组寻址(可以通过计算偏移量直接获取第N位置的内容)
对比链表寻址(是没有办法直接计算得到第N位置的内容,所以它不是一个常数操作)
二、时间复杂度的概念
假设数据量为N的样本中,执行完整个流程,描述常数操作的数量关系。通常由O()表示,是一种渐进时间复杂度。
若存在函数 f(n),使得当n趋近于无穷大时,T(n)/ f(n)的极限值为不等于零的常数,则称 f(n)是T(n)的同数量级函数。
记作 T(n)= O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。
T(n)为常数操作执行次数
简单理解,时间复杂度就是把T(n)简化为一个数量级,这个数量级可能为 n,n^2…
时间复杂度的推导
1.分解算法流程中的每一步直至常数操作,并进行T(n)的计算
2.只保留时间函数的最高阶项
下面利用简单选择排序进行说明:
选择排序流程:
- 0 ~ N-1 中,选择最小的数,并与第1位进行交换
- 1 ~ N-1 中,选择最小的数,并与第2位进行交换
- …
- 直到 N-1位置
分解至常数操作
- 0 ~ N-1中,查看 并进行 N-1次比较(1),将最小值放到0位置(1) 此时 进行了 N-1次比较 1次交换
- 1 ~ N-1中,查看并进行N-2次比较(1),将最少值放到1位置(1)
- …
我们可以得出总次数 是一个等差数列的求和 (N + N-1 + N-2 … + 1)=> T(n) = aN^2 + bN + C
因此得出简单选择排序时间复杂度为 O(N^2)
算法实现:
public static void insertSort(int[] arr){ if(arr == null || arr.length < 2) return; for(int i = 0 ; i < arr.length - 1 ; i ++){ int minIndex = i; for(int j = i + 1 ; j <= arr.length - 1; j ++){ minIndex = arr[j] < arr[minIndex] ? j : minIndex; } // if(i != minIndex) { // swap(arr, i, minIndex); // } swap(arr,i,minIndex); } }
递归函数时间复杂度估计
子规模一致
T(n