给定一个查询算法代码,实现如下:
/**
* 线性查找
*
* @param a 数组
* @param target 查找目标
* @return 目标在数组中的索引,没有就返回 -1
*/
public static int linerSearch(int[] a, int target) {
for (int i = 0; i < a.length; i++) {
if (a[i] == target) {
return i;
}
}
return -1;
}
和二分查找进行比较,时间复杂度的算法 (O)
/**
* 和二分查找做比较,采用事前分析方法【假设执行每一行代码的时间相同】。当 数组 a 中有 n 个数据
* 1、最坏的情况,没有找到数据
* 【linerSearch】没有找到数据,代码全部执行,代码的执行次数分别是:
* int i = 0; 1
* i < a.length; n + 1(最后一次比较)
* i++ n
* a[i] == target n
* return -1; 1
*
* 那么一共执行次数就是 3*n + 3 可以发现 执行次数 和 n 成一次函数线性相关。
*
* 看【binarySearchBasic】 没有找到数据
* 在二分查找中,因为正数时向下取整,所以当右侧没有找到时用时会多一些。
* 例如在 [2,6,7,8,9,12,13,45] 中 ,查找 50 的循环次数一定比查找 1 执行的代码行数多。
*
* int i = 0, j = a.length - 1; 2
* return -1; 1
* 元素个数 循环次数
* 4 - 7 3 log_2(4) = 2
* log_2(7) = 2.xxx 向下取整即可
* 8 - 15 4 log_2(8) = 3
* 16 - 31 5 log_2(16) = 4
* 32 - 63 6 log_2(32) = 5
* ...
* 可以发现元素个数和循环次数是一个以 2 为底的对数关系 ;循环系数 = log_2(元素个数) + 1
*
* 那么循环次数(L) = floor(log_2(n)) + 1;floor 函数表示向下取整数
*
* i <= j; L + 1
* int m = (i + j) >>> 1; L
* target < a[m] L
* a[m] < target L
* i = m + 1; L
*
* 总次数: 5 * L + 4 = 5 * [floor(log_2(n)) + 1] + 4
*
* 现在就可以做比较了。设每一行代码执行时间为 t
* 当数组有 4 个元素时:
* 线性查找:[3*n + 3] * t = 15t
* 二分查找:[5 * [floor(log_2(n)) + 1] + 4] * t = 19t
* 在数据量小的时候,线性查找还有优一些
*
* 当数据元素是 1024 时:
* 线性查找:3 * 1024 + 3 = 3075 t
* 二分查找:5 * (10 + 1) + 1 + 4 = 55 t
* 当数据量大的时候,差别就非常大了。
*
*
*
* 时间复杂度:一个算法的执行,随着数据规模的变大,而增长的时间成本
* 时间复杂度不依赖于环境因素【硬件环境和软件环境】
*
* 时间复杂度如何体现呢?
* 假设算法要处理的数据规模是 n,代码执行行数用 f(n) 表示。
* 线性查找:f(n) = 3 * n + 3;
* 二分查找:f(n) = 5 * [floor(log_2(n)) + 1] + 4
* 为了更加直观的看出 f(n) ,可以对齐进行简化,让真实和化简后的函数结果近似,就用基于 O 表示
* 按照求极限的方式当 n -> 正无穷大时,保留一项即可。 可以将常数和系数全部省略。
* 3 * n + 3 ~ n ~ O(n)
* 5 * [floor(log_2(n)) + 1] + 4 ~ log_2(n) ~ O(log_2(n)) ~ O(log(n))
*
* 常见的时间复杂度:
* 1、O(1):常量级,最优的时间复杂度
* 2、O(log(n)):对数时间,和底数没有关系
* 3、O(n):线性时间
* 4、O(n*log(n)):拟线性时间,和 O(n) 差不多
* 5、O(n^2):平方时间
* 6、O(2^n):指数时间
* 7、O(n!):阶乘时间
* 8、O(n^n):时间复杂度最差。
*
* 效率排序:O(1) < O(log(n)) < O(n) < O(n*log(n)) < O(n^2) < O(2^n) < O(n!) < O(n^n)
*
*
*/
空间复杂度:和时间复杂度类似,一般也使用 O 表示:一个算法执行随着数据规模的变大,从而增长的额外空间成本。
说明:在大多数情况下,都考虑牺牲空间复杂度从而优化时间复杂度。