递归的两个特点:
1.调用自身
2.结束条件
def func1(x): if x>0: print(x) func1(x-1) # 5 4 3 2 1 def func2(x): if x>0: func2(x-1) print(x) # 1 2 3 4 5
时间复杂度
用来评估算法运行效率
print('Hello World') # O(1)
for i in range(n): # O(n) print('Hello World')
for i in range(n): # O(n2) for j in range(n): print('Hello World')
for i in range(n): # O(n3) for j in range(n): for k in range(n): print('Hello World')
print('Hello World') # O(1) print('Hello Python') print('Hello Algorithm')
for i in range(n): # O(n2) print('Hello World') for j in range(n): print('Hello World')
for i in range(n): # O(n2) for j in range(i): print('Hello World')
while n > 1: # O(logn)或O(log2n) print(n) n = n // 2 n=64时输出: 64 43 16 8 4 2
时间复杂度是用来估计算法运行时间的一个单位
一般来说,时间复杂度高的算法比复杂度低的算法慢
常见的时间复杂度(按效率排序)
O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n2logn)<O(n3)
如何一眼判断时间复杂度?
1.循环减半的过程 --> O(logn)
2.几次循环就是n的几次方的复杂度
空间复杂度
用来评估算法内存占用大小的一个式子
线性查找
def linear_search(data_set, value): # 传入列表和要查找的值 for i in range(range(data_set)): if data_set[i] == value: return i return
# 时间复杂度 O(n)
二分查找
从有序列表的候选区data[0:n]开始,通过对待查找的值与候选区中间值的比较,可以使候选区减少一半
def bin_search(data_set, val): low=0 high=len(data_set)-1 while low <= high: mid = (low+high)//2 if data_set[mid] == val: return mid elif data_set[mid] < val: low = mid + 1 else: high = mid - 1 return
# 时间复杂度O(logn)
def random_list(n):
result = []
ids = list(range(1001,1001+n))
a1 = ['zhao','qian','sun','li']
a2 = ['li','hao','','']
a3 = ['qiang','guo']
for i in range(n):
age = random.randint(18, 60)
id = ids[i]
name = random.choice(a1)+ random.choice(a2)+ random.choice(a3)
排序
将无序列表转化为有序列表
冒泡排序
def bubble_sort(li): for i in range(len(li)-1): for j in range(len(li)-i-1): if li[j] > li[j+1]: li[j],li[j+1] = li[j+1],li[j]
data = list(range(10000))
random.shuffle(data)
bubble_sort(data)
print(data)
#改进版
如果冒泡排序中执行一趟而没有交换,则列表已经是有序状态,可以直接结束算法
def bubble_sort(li): for i in range(len(li) - 1): #i 第几趟
exchange = False # 一趟过去后交换变量就会由False变为True for j in range(len(li) - i - 1): if li[j] > li[j+1]: li[j], li[j+1] = li[j+1],li[j]
exchange = True
if not exchange:
break # 如果没有交换就结束,这种极端情况出现在已经排好序的情况下就不用先重复走上那么多趟 data = list(range(10000)) random.shuffle(data) bubble_sort(data) print(data)
#时间复杂度O(n2)
选择排序
一趟遍历记录最小的数,放到第一个位置
再一趟遍历记录剩余列表中最小的数,继续放置
......
如何选出最小的数?
def select_sort(li): for i in range(len(li) - 1): #i是趟数 min_loc = i #最小的是从i开始的,每一趟找一个最小的数 for j in range(i+1,len(li)): #从i后面开始比 if li[j] < li[min_loc]: min_loc = j li[i], li[min_loc] = li[min_loc], li[i] data = list(range(1000)) random.shuffle(data) select_sort(data) print(data)
#复杂度 O(n2)
插入排序
列表被分为有序区和无序区两个部分,最初有序区只有一个元素
每次从无序区选一个元素,插入到有序区的位置,直到无序区变空
def insert_sort(li): for i in range(1, len(li)): #从索引是1的位置开始到最后 tmp = li[i] j = i -1 #前面的位置 while j >= 0 and li[j] > tmp: li[j+1]=li[j] j = j -1 li[j+1] = tmp
data = list(range(1000))
random.shuffle(data)
insert_sort(data)
print(data)
#复杂度 O(n2)