您的位置:首页 > 编程语言 > Python开发

Big O notation大零符合 入门讲解

2017-07-11 21:04 435 查看
Big O notation大零符号一般用于描述算法的复杂程度,比如执行的时间或占用内存(磁盘)的空间等,特指最坏时的情形。

Linus Torvalds说过“Talking is cheap, show me the code.”,那我们直接从代码(Python)上来学习Big O吧。

O(1)

def isFirstElementNull(elements, value):
return elements[0] == value
#print isFirstElementNull(["1","2"],"1")


无论输入参数是什么,这个函数就只执行一次,所以它的复杂度为O(1)。

O(N)

def containsValue(elements, value):
for e in elements:
if e == value:
return True
return False
#print isFirstElementNull(["1","2"],"1")


这里有一个for循环,如果运气好就执行一次(elements里第一个值就跟value一样),运气不好就要执行N次(N等于elements的长度,碰巧elements里最后一个值跟value一样),因为Big O是表示最坏时情形,所以这个函数的复杂度为O(N),好理解吧。

O(N2)

def containsDuplicates(elements):
for m in range(len(elements)):
for n in range(len(elements)):
if (m != n) and elements[m] == elements
:
return True
return False
#print containsDuplicates(["1","2","3","2"])


这里有两个嵌套的for循环,所以执行最多的次数肯定为两个for循环次数相乘,即N*N(N等于elements长度),所以这个函数的复杂度为O(N2)。

O(2N)

def fibonacci(num):
if num < 2:
return num
return fibonacci(num - 2) + fibonacci(num - 1)
#print fibonacci(5)


这是计算斐波那契数的函数,用递归方式实现,不太容易一下就看出执行了多少次。不要紧,我画了个图,这样就方便直观了。



容易看出执行多少次了吧,即2的N次方,所以这个函数的复杂度为O(2N)。

对了,斐波那契函数是什么鬼,看看下面这个图你立马就明白了。



O(logN)

是不是一看log(对数)就头大,其实没那么复杂,在看例子前我们先复习复习高中知识,什么是log。

如果x的y次方等于n(x>0,且x不等于1),那么数y叫做以x为底n的对数(logarithm)

记作logxn=y。其中,x叫做对数的底数。

1.底数为10时,写为lg;

2.底数为e时,称为自然对数写为ln,这个在高等数学中用的很多;

3.底数为2时,主要用在计算机中,写为log,也就是不写底数;

所以我们说的logN其实就是log2n

我们以Binary Search(也叫拆半查询和二分查询)为例,感觉查询过程就跟切西瓜一样,先中间切一刀,然后选一块,再在选定的半个西瓜上再来一刀,再决定选哪块,再切再选,最后找到满意的,即1/2,1/4,1/8,1/16…这样下去。以下是算法脚本

public int binarySearch(int array[],int key) {
int begin = 0;
int end = array.length - 1;
while (begin <= end) {
int mid = begin + (end - begin) / 2;
if (array[mid] > key){
end = mid - 1;
}
else if (array[mid] < key){
begin = mid + 1;
}else{
return mid;
}
}
return -1;
}


以下是测试程序

int[] a1 = {1,2,3,4,5,6,7,8,9,11,22,33,44,55,66,77,88,99,100};
int result = binarySearch(a1, 4);
System.out.println(result);
//output: 3


其实这样一刀一刀的找就是2的倍数关系,比如切了3刀找到,那就有8块了(其实是4块,因为你只切选中的那一块,但为了计算方便,我们就当把西瓜都切了),即2的3次方,如果切5刀找打,那就有32块,即2的5次方,所以这个算法的时间复杂度就是O(log2N),即O(logN)。

注意,时间复杂度是个近似值,比如O(2N)就是O(N),O(3N+5)就是O(N),这个值要表达的是个复杂度趋势,记住这点很重要。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 python