一、一些概念
注意:后面出现log,都是以2为底,我简写了。
1、算法是什么
算法是一组完成任务的指令,任何代码片段都可视为算法。
2、递归
假如说你有一个扫地机器人,它每天的工作状态是这样的:
巡逻,发现有垃圾,清理(假设它很懒,一天只清扫一个地方)。
这之中就含有递归。
那个巡逻,判断有没有垃圾的,然后发现没有垃圾,继续巡逻,就是一个递归。
可以这样理解,递归就是调用函数自身。那么清理它呢?清理叫基线,是跳出这种调用的结果。这里的no会进入递归,或者这里也可以叫循环,这个no就叫递归条件,这个yes同理叫基线条件。
3、大O表示法
一个代码片段,或者说算法,如果只执行一次,就没有多少复用性。所以我们要用循环,要用递归。循环是在一小个地方的复用,是狭义的。递归函数本质上是函数,可以在整个文件中复用,所以应用范围更广。
一个重复性的工作,如果我们用递归函数来解决,是不是等于整个函数执行的次数,乘以它每次运行的时间?每次运行的时间为t,运行的次数为x,总时间为T。则:
但我们并不是每次都能准确知道运行次数的,同一个算法,可能因为运气不同,而导致x不同。(有的算法平均情况下x比较小,但是最糟情况下x大)随着总量的变化,x中有不变的部分,还有变化的部分,变化的部分用函数表示O,不变的部分用常数C表示。这个函数部分是用O表示的,所以叫大O表示法,它代表的是运行次数。
还不理解,看看下面的就懂了。
二、简单查找与二分查找
1、简单查找
这里有一个有序列表 list = [1,2,3,4,5,6,7]
我告诉你A对应的是第0个位置,请你告诉我C对应的是什么?
对了,是第2个位置。(这个位置可以叫偏移量,也可以叫索引)
我想了一个整数,它在0~一百万之间,你能猜到吗?如果让计算机来猜,它一定猜半天,因为它会从0开始问,是这个吗?假如说正好是最后一个数字,那么计算机要猜一百万次。
计算机的这种从头开始的方法叫简单查找,假如说一个有序列表有10亿个元素(10亿是大数据的起点),则最糟情况下(正好是最后一个元素)它的时间为:
O(n)的意思就是执行n次
2、二分查找
如果是你,你会怎么问呢,你会从中间开始,问是大了还是小了。
我们让计算机聪明点,学习你的方法,则时间为:
可能没什么概念,假如计算机简单查找一次的时间是10ms,二分查找一次的时间是100ms(毕竟多了个判断的过程,时间肯定更多。当然计算机没这么慢。)
3、代码
#猜数字的二分查找示例
from math import ceil#导入向上取整模块
arr = list(range(150))#生成一个列表
player_element = int(input('请输入一个数字'))
def binary_search(arr,player_element):
low = 0#第一个元素索引
high = len(arr)-1#最后一个元素索引
mid = ceil((low+high)/2)#中间元素索引
if high:#当列表长为1时就停止
#从中间分成两个列表
arr_left = [i for i in arr if i < arr[mid] ]
arr_right = [i for i in arr if i >= arr[mid] ]
if player_element == arr[mid]:
print(arr[mid])
#如果等于就输出,不等就递归
elif player_element < arr[mid]:
return binary_search(arr_left,player_element)
elif player_element > arr[mid]:
return binary_search(arr_right,player_element)
binary_search(arr,player_element)