二分查找
二分查找需要输入一个有序的元素列表,如果要查找的元素包含在其中,二分查找将返回其位置,否则返回null。
例:
现有有序数组为[1,2,3,…,99,100],需要找到63
使用二分查找,每次取剩余数组的中间值判断,判断后,将不存在目标数据的部分排除
即,先取50,判断50<63,则排除小于50的部分,剩余数组为[51,52,53…,99,100]
再取75,判断75>63,排除大于75部分,剩余为[51,52,53…73,74]
以此类推,最终能找到目标数据
且,针对该数组中的任何数据,都能在7次之内找到,即,需要判断的次数
n
<
l
o
g
2
100
n < log_2 100
n<log2100
代码实现如下:
public class Binary
{
/**
* 二分查找,返回目标元素的下标
* @param arrays 有序数组
* @param aim 目标元素
* @return 数组内存在则返回对应下标;否则返回-1
*/
public int Search(int[] arrays,int aim)
{
int low = 0;
int high = arrays.length - 1;
while(low <= high)
{
printArray(arrays,low,high);
int mid = (int)Math.floor((low+high)/2);
System.out.println("low:"+low+"high:"+high+"mid:"+mid);
if(arrays[mid] == aim)
{//已经找到目标,返回对应下标
return mid;
}
if(arrays[mid] < aim)
{//取右边
low = mid + 1;
}
if(arrays[mid] > aim)
{//取左边
high = mid - 1;
}
}
return -1;
}
/**
* 截取数组内部分数据打印
* @param arr
* @param low
* @param high
*/
private void printArray(int[] arr,int low,int high)
{
String strArray = "[";
for(int printLow = low;printLow <= high;printLow ++)
{
if(printLow != low)
{
strArray += ",";
}
strArray += arr[printLow];
}
strArray += "]";
System.out.println(strArray);
}
public static void main(String args[])
{
Binary bin = new Binary();
int[] arr = {1,2,3,4,5,6,7,8,9,10};
System.out.println(bin.Search(arr, 6));
}
}
大O表示法
大O表示法是什么
-
大O表示法是一种特殊的表示法,用于指出算法的速度有多快。
-
大O表示法指的并非是以秒为单位的速度。
-
它让你能够比较操作数,指出了算法运行时间的增速。
-
谈论算法的速度是,说的是随着输入的增加,算法的耗时将会以何种方式增加
-
大O表示法指出的是最坏情况下的运行时间。
5种常见的大O运行时间
O(log n) ——对数时间,包括二分查找。
O(n) ——线性时间,包括简单查找
O(n*log n) —— 快速排序
O(n^2) —— 选择排序
O(n!) —— 旅行商问题
旅行商问题
这是一个运行时间极长的算法,并且被认为没有改进的余地。
问题描述
有一位旅行商,他需要前往5个城市,同时要确保旅程最短。
方案
因为需要旅途最短,需要考虑前往各个城市的顺序。每种顺序都需要算出总旅途,然后才能选出最短的路线。
当有5个城市的时候,有120种路线。
当有7个城市的时候,有5040种路线。
n个城市时,有n!种路线。
即该算法的速度为O(n!)。
方案
因为需要旅途最短,需要考虑前往各个城市的顺序。每种顺序都需要算出总旅途,然后才能选出最短的路线。
当有5个城市的时候,有120种路线。
当有7个城市的时候,有5040种路线。
n个城市时,有n!种路线。
即该算法的速度为O(n!)。
面对这个问题若想更快的解决,我们能做的只有找出近似的答案。