算法衡量指标:正确性,可读性,易维护性,运行时间
算法计算时间可以通过复杂度的阶表示:对数阶(
log2x
log
2
x
),线性阶(x),多项式阶(
x2
x
2
),指数阶(
2x
2
x
)
大O表示法,表示在。。。。。阶,线性时间算法的阶为:O(n)
#找出一个列表中最小值的索引
def index_of_min(shuffle_list):
index_min = 0
for i in range(len(shuffle_list)):
if shuffle_list[i] < shuffle_list[index_min]:
index_min = i
return index_min
index_of_min([3,6,1,4,5])#算法必须经过n-1次比较,复杂度为O(n)
#numpy中函数实现找出列表中最小值的索引
import numpy as np
np.argmin([3,6,1,4,5])
实现一个顺序搜索算法,判断一个数是否在指定的无序列表中
def order_search(target,lst):
for i in lst:
if i == target:
return True
return False
order_search(3,[4,5,6,7])#算法最少判断一次,最多要判断n次,算法复杂度为O(n)
实现一个二叉树算法,判断一个数是否在指定的有序列表中
def binary_search(target,ordered_lst):
left = 0
right = len(ordered_lst) - 1
while left <= right:
center = (left + right) // 2
if target == ordered_lst[center]:
return True
else:
if target < ordered_lst[center]:
right = center - 1
else:
left = center + 1
return False
binary_search(300,[3,5,6,7,9,10,12,18,30])
二叉树搜索算法最少执行一次,做多执行k次,使得
n/2k=1
n
/
2
k
=
1
,所以算法复杂度为:O(
log2n
log
2
n
)。
可以发现二叉树搜索算法比顺序搜索算法更高效,但是前提是列表必须是有序的。
一个类对象如果能够识别比较运算符,比如==,<,>那类中需要定义下面的魔法方法:
__eq__,__lt__,__gt__
#实现能一个进行比较操作的类
class compare_operation():
'''该类实现比较操作'''
def __init__(self,data):
self.data = data
def __eq__(self,other):
return self.data == other.data
def __lt__(self,other):
return self.data < other.data
def __gt__(self,other):
return self.data > other.data
a = compare_operation(4)
b = compare_operation(5)
用选择排序算法对列表排序,算法思路:从第一个位置开始,先找到列表中最小项,如果该项不是第一的位置,就交换着两个位置。接着重从第二个位置开始,重复上面的步骤,直到算法达到列表的最后一个位置。
def seleclt_sorted(shuffled_lst):
index_location = 0#算法开始的位置
while index_location < len(shuffled_lst) - 1:#从第一个位置开始循环
min_index = index_location
index = index_location + 1
while index < len(shuffled_lst):#从算法开始位置,找出列表中的最小值
if shuffled_lst[min_index] > shuffled_lst[index]:
min_index = index
index += 1
shuffled_lst[index_location],shuffled_lst[min_index] = shuffled_lst[min_index],shuffled_lst[index_location]#最小值和算法开始位置值交换
index_location += 1#后面循环起始位置加1
return shuffled_lst
选择排序算法总的循环次数为:n-1 + n-2 + n-3 +……+1,也就是 12n2−12n 1 2 n 2 − 1 2 n ,算法复杂度为O( n2 n 2 )
冒泡排序对无序列表排序,算法思路:从列表头部开始,两两比较,数据大的就交换位置,以冒泡的方式将最大项排到列表最后
def bubble_sorted(shuffled_lst):
for i in range(len(shuffled_lst)):
for j in range(i+1,len(shuffled_lst)):
if shuffled_lst[i] > shuffled_lst[j]:
shuffled_lst[i],shuffled_lst[j] = shuffled_lst[j],shuffled_lst[i]
return shuffled_lst
冒泡算法和选择排序算法循环次数一样,算法复杂度为O( n2 n 2 )
插入排序法,算法思路:类似排扑克牌,拿到第i张牌,与前i-1比较,插到合适的位置
def insection_sorted(shuffled_lst):
i = 1#第一个要插入的值
while i < len(shuffled_lst):
insert_value = shuffled_lst[i]
j = i -1
while j >= 0:
if insert_value < shuffled_lst[j]:
shuffled_lst[j+1] = shuffled_lst[j]#如果当前值比要插入的值要大,就后移一位
j -= 1
else:
break #前i-1个值都是已经排序的好的,所以循环到大于的情况就可以停止了
shuffled_lst[j+1] = insert_value#插入值
i += 1#插入的值的索引自增
return shuffled_lst
插入算法外部循环n-1,内部循环在所有数据都是没排序时候,外部循环第一次循环,内不循环一次,第2次循环,内部循环2次,所以总次数为 12n2−12n2 1 2 n 2 − 1 2 n 2 ,算法复杂度为:O( n2 n 2 )
快排算法,算法思路:列表中选一个点做为基准点(一般可以选第一个元素),将列表中其他与该基准点比较,小的放在左边,大的放在右边,最后对分好的左右子列表重复递归使用该过程。遇到少于两个元素的子列表就结束该过程。
#快排实现
def sort_partion(shuffled_list,left,right):
pivot_index = left
pivot = shuffled_list[left]
for i in range(left+1,right+1):
if shuffled_list[i] < pivot:#遍历列表开始判断该数是否小于基数
pivot_index += 1
if pivot_index != i:
shuffled_list[pivot_index],shuffled_list[i] = shuffled_list[i],shuffled_list[pivot_index]
shuffled_list[left],shuffled_list[pivot_index] = shuffled_list[pivot_index],shuffled_list[left]
return pivot_index
def quick_sort(shuffled_list,left,right):
if left < right:
pivot_index = sort_partion(shuffled_list,left,right)
quick_sort(shuffled_list,left,pivot_index-1)
quick_sort(shuffled_list,pivot_index+1,right)
return shuffled_list