章节内容
- 二分查找
- 算法复杂度
二分查找
本书先以一个简单的查找算法开始讲起。
我们知道对于一个列表,我们可以遍历列表中的每个元素,看是不是我们想要的。最糟的情况下,查找的次数等于列表元素的个数。
如果是一个有序的元素列表,我们可以选择更佳的查找算法:二分查找。
二分查找的算法思想:先从列表中间元素开始找,如果中间元素比目标大,则在前半部分列表中继续以这种方式查找;如果中间元素比目标大,则在前半部分继续以此方式查找,如果等于则找到。
学过高中数学的人都知道,如果元素的个数为N个,则最糟情况下的查找次数为以2为底N的对数。
java版二分查找代码如下:
public static int recursionBinarySearch(int[] arr,int key,int low,int high){
if(key < arr[low] || key > arr[high] || low > high){
return -1;
}
int middle = low + (high - low) / 2;//初始中间位置
if(arr[middle] > key){
//比关键字大则关键字在左区域
return recursionBinarySearch(arr, key, low, middle - 1);
}else if(arr[middle] < key){
//比关键字小则关键字在右区域
return recursionBinarySearch(arr, key, middle + 1, high);
}else {
return middle;
}
}
大O表示法指出的是算法在最糟情况下的运行时间
除最糟情况下的运行时间,也应该考虑平均情况的运行时间。
算法的复杂度不是指时间,而是操作数的增速
经常遇到的5种大O运行时间,从快到慢排序:
- O(logn),也叫对数时间,这样的算法包括二分查找
- O(n),也叫线性时间,这样的算法包括简单查找
- O(n*logn),快排,归并排序
- O(n^2),选择排序,插入排序,冒泡排序等排序算法
- O(n!),旅行商问题
PS:还有Floyd最短路径算法的时间复杂度是(n^3)
旅行商问题
旅行商问题是指一个旅行商需要前往N个城市,同时需要确保旅程最短。
算法实现:计算每一种排序的总路程,再挑选出最短的路线。N个城市总共路线数有N!种,所以算法复杂度位O(n!)
补充知识:
旅行时问题属于NP问题。何为NP?在我们经常遇到的算法的时间复杂度为以上五种,它们的时间复杂度都可以用O(n^k)来表示,其中k是个常数。
因此,这些算法都是多项式时间算法,能用多项式时间算法解决的问题被称为P问题(Polynomial)。
无法用多项式时间解决的问题,比如旅行商问题(O(n!)),O(2^n)的算法成为NP问题(Non-deterministic Polynomial)
小结
- 二分查找的速度比简单查找快得多
- O(logn)比O(n)快。需要搜索的元素越多,前者比后者就快的越多
- 算法运行时间并不以秒为单位
- 算法运行时间是从其增速的角度度量的
- 算法运行时间用大O表示法表示