常用算法
1 算法的定义
算法(algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,就能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合与某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任何。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。
算法应具备以下特性:
a 有穷性(Finiteness) 算法的有穷性是指算法必须能在执行有限个步骤之后终止,并且每一个步骤在可接收的时间内完成。
b 确切性(Definiteness) 算法的每一步骤必须有确切的定义
c 输入项(Input) 一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓讴歌输入是指算法本身具备初始条件
d 输出项(Output) 一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的
e 可行性(Effectiveness) 算法的每一步都必须是可行的,也就是说,每一步都能够通过执行有限次数完成
f 正确性
h 可读性
g 健壮性
2 算法时间复杂度
在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。算法的时间复杂度,也就是算法的时间量度,T(n)= O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度。其中f(n)是问题规模n的某个函数。
用大写O()来提现算法时间复杂度,称为大O记法。一般,随着n的增长,T(n)增长最慢的算法为最优算法。
推导大O阶方法:
* 用常数1取代运行时间中的所有加法常数。
* 在修改后的运行次数函数中,只保留最高阶项。
* 如果最高阶项存在且不是1,则去除与这个项相乘的常数。
常用的时间复杂度有:
a 常数阶O(1),不管这个常数是多少,我们都记作O(1),而不能是O(3)、O(12)等。
b 线性阶O(n),线性阶的循环结构会复杂很多,关键就是要分析循环结构的运行情况。
c 对数阶()
3 常用排序算法
a 冒泡排序,复杂度:O(n*n)和O(1)稳定, 原理:将待排序的元素看做是竖着排列的“气泡”,较小的元素比较轻,从而往上浮。
冒泡排序(Bubble Sort),是一种比较简单的排序算法。
1 data = [6,5,7,4,8,1,2,9,3,0] 2 n = 0 3 for i in range(len(data)): 4 for j in range(len(data) - i -1):#必须要减一,否则超出列表的范围 5 if data[j] > data[j+1]: 6 tmp = data[j] 7 data[j] = data[j+1] 8 data[j+1] = tmp 9 print(data) 10 输出 11 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b 插入排序(类似于整理扑克牌),复杂度:O(N*N)和O(1)稳定,原理:逐一取出元素,在已经排序的元素序列中从后往前扫描,放到适当的位置。
1 data_set = [ 9,1,22,9,31,-5,45,3,6,2,11 ] 2 for i in range(len(data_set)): 3 #position = i 4 while i > 0 and data_set[i] < data_set[i-1]:# 右边小于左边相邻的值 5 tmp = data_set[i] 6 data_set[i] = data_set[i-1] 7 data_set[i-1] = tmp 8 i -= 1 # 前提是右边的序列已经排好 9 print (data_set)
c 选择排序,复杂度:O(N*N)和O(1)不稳定,原理:在长度为N的无序数组中,在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换,如此循环至到选择排序完成。
1 data_set = [9, 2, 22, 31, 45, 3, 6, 1, 11] 2 smallest_num_index = 0 # 初始列表最小值,默认为第一个 3 loop_count = 0 4 for j in range(len(data_set)): 5 for i in range(j, len(data_set)): 6 if data_set[i] < data_set[smallest_num_index]: # 当前值 比之前选出来的最小值 还要小,那就把它换成最小值 7 smallest_num_index = i 8 loop_count += 1 9 else: 10 print("smallest num is ", data_set[smallest_num_index]) 11 tmp = data_set[smallest_num_index] 12 data_set[smallest_num_index] = data_set[j] 13 data_set[j] = tmp 14 print(data_set) 15 print("loop times", loop_count)
d 快速排序(quick_sort) 时间复杂度为O(nlog2n) 不稳定,原理:选择一个基准元素,通常祖安泽第一个或最后一个元素,通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小,另一部分记录的元素值比基准值大。
然后分别对这两部分,用同样的方法继续进行排序,直到整个序列有序。
1 def quickSort(num,l,r): 2 if l>=r:#如果只有一个数字时,结束递归 3 return 4 flag=l 5 for i in range(l+1,r+1):#默认以第一个数字作为基准数,从第二个数开始比较,生成索引时要注意右部的值 6 if num[flag]>num[i]: 7 tmp=num[i] 8 del num[i] 9 num.insert(flag,tmp) 10 flag+=1 11 print("~~~",num) 12 quickSort(num,l,flag-1)#将基准数前后部分分别递归排序 13 quickSort(num,flag+1,r)#注意:python递归层次最大为998 14 num=[5,4,7,-2,6,3,2,3] 15 quickSort(num,0,7) 16 print(num)

浙公网安备 33010602011771号