算法目录
-
二分查找
-
大O表示法
-
选择排序
-
递归
-
快速排序,分而治之(D&C)
-
散列表——字典
-
广度优先搜索——BFS
-
Dijkstra算法
-
贪婪算法
二分查找
1 # 要求list是有序表,num是要查找的数字
2 # 二分查找貌似只能查找数值表
3 def binary_search(list, num):
4 low = 0
5 high = len(list) - 1 # 因为python数组(列表)是从0开始索引的
6
7 while low <= high:
8 mid = (low + high)
9 guess = list[mid]
10 if guess == num:
11 return "found it is " + str(mid)
12 if guess > num:
13 high = mid - 1
14 else:
15 low = mid + 1
16 return "not found"
17
18 # python数组不同于matlab数组,python中间要用逗号隔开,而matlab不用
19 my_list = [1, 3, 5, 7, 9, 11, 13]
20 print(binary_search(my_list, 6))
21 print(binary_search(my_list, 9))
大O表示法
1. 能够比较操作数,表示算法运行时间的增速
2. 给出了一个时间的上限
3. 算法的速度并非时间,而是操作数的增速
4. O(logn)——对数时间(二分查找)
5. O(n)——线性时间(顺序查找)
6. O(n*logn)——快速排序
7. O(n^2)——选择排序
8. O(n!)——旅行商问题的解决办法
9. 常量并不会影响到大O表示法
选择排序
* 计算机内存如同一大堆抽屉
* 需要存储多个元素时可采用链表或数组
* 数组元素都在一起,因此读取速度快
* 链表是分开的,但是插入和删除速度很快
* 链表数组查找比数组慢,比链表快;插入比数组快,与链表相当
* 同一数组元素的类型均相同
1 寻找数组中的最小值的索引
2 def find_smallest_index(arr):
3 smallest = arr[0]
4 smallest_index = 0;
5 # python中检查数组长度的函数是len,而matlab中是length
6 for i in range(1, len(arr)):
7 if arr[i] < smallest:
8 smallest = arr[i]
9 smallest_index = i
10 return smallest_index
11
12 # 对数组进行排序
13 def selection_insort(arr):
14 # create new array
15 new_arr = []
16 for i in range(len(arr)):
17 smallest_index = find_smallest_index(arr)
18 # array.pop()只能根据索引值弹出元素,so pop()应传入索引值
19 new_arr.append(arr.pop(smallest_index))
20 return new_arr
21
22 mess_arr = [3, 1, 9, 2, 5, 4]
23 print("This is uninsort array: " + str(mess_arr))
24 insorted_arr = selection_insort(mess_arr)
25 print("This is insorted array: " + str(insorted_arr))
递归
* 使用循环程序性能可能更高,使用递归程序可能更容易理解
* 递归条件——让函数调用自己;基线条件——让函数不再调用自己
* 所有函数调用都进入递归调用栈
1 # 一个计算数学阶乘的递归调用
2 def func(x):
3 if x == 1:
4 return 1
5 else:
6 return x * func(x-1)
7
8 print(func(3))
9
10
11 #一个计算数组和的递归调用
12 def func(arr):
13 if arr == []:
14 return 0
15 else:
16 # 这里不能用arr[0] + func()因为基线条件是arr==[]当arr
17 # 只有一个元素时python会将arr变为一个int数值,而不会是数组
18 return arr.pop() + func(arr)
19
20 arr = [2, 3, 4]
21 print(func(arr))
快速排序,分而治之(D&C)
* 找出基线条件(很可能是一个空数组或者只包含一个元素的数组)
* 不断将问题分解直至满足基线条件
* 快速排序:
* 选取基准值
* 将数组分为两个子数组:小于基准值的元素和大于基准值的元素
* 对这两个子数组进行快速排序
View Code
View Code
View Code
1 # 快速排序——by myself
2 def quickly_sort(arr):
3 # 两个基线条件
4 if len(arr) < 2:
5 return arr
6 # 直接选取数组元素第一个当作基准值——递归条件
7 reference_value = arr[0]
8 larger_arr = []
9 smaller_arr = []
10 for i in range(1,len(arr)):
11 if arr[i] > reference_value:
12 larger_arr.append(arr[i])
13 # arr.pop(i)
14 else:
15 smaller_arr.append(arr[i])
16 # arr.pop(i)
17 return quickly_sort(smaller_arr) + [reference_value] + quickly_sort(larger_arr)
18
19 mess_arr = [3, 1, 9, 2, 5, 4]
20 print("This is uninsort array: " + str(mess_arr))
21 insorted_arr = quickly_sort(mess_arr)
22 print("This is insorted array: " + str(insorted_arr))
1 # 快速排序——by others
2 def quickly_sort(arr):
3 # 基线条件
4 if len(arr) < 2:
5 return arr
6 else:
7 # 选取基准值——递归条件
8 pivot = arr[0]
9
10 # 简洁明了选出较大数组与较小数组
11 larger = [i for i in arr[1:] if i > pivot]
12 smaller = [i for i in arr[1:] if i <= pivot]
13 # 递归调用
14 return quickly_sort(smaller) + [pivot] + quickly_sort(larger)
15
16 mess_arr = [3, 1, 9, 2, 5, 4]
17 print("This is uninsort array: " + str(mess_arr))
18 insorted_arr = quickly_sort(mess_arr)
19 print("This is insorted array: " + str(insorted_arr))
散列表——字典
* 散列函数——将输入映射到数字;同一输入映射一致,不同输入映射到不同的数字
* 良好散列表包括:较低的填装因子0.7以下,良好的散列函数SHA函数
* 散列表查找(O(1))、删除、插入都非常快
* 散列表适用于模拟映射关系、防止重复以及缓存数据
1 # 散列表——字典
2 # 创建字典的两种方案
3 price_list = dict()
4 price_list = {}
5
6
7 # 添加数据
8 price_list["apple"] = 0.67
9 price_list["milk"] = 1.49
10 price_list["bread"] = 0.49
11
12 print(price_list)
13 print(price_list.keys())
14 print(price_list.values())
15 print(price_list.items())
16
17 # 判断是否在散列表中
18 flag = price_list.get("apple")
19 print(flag)
20 # 不同大小写诗不同与阿奴
21 flag = price_list.get("Apple")
22 print(flag)
23 flag = price_list.get("banana")
24 print(flag)
广度优先搜索——BFS
* 用于解决最短路径
* 利用import collection import deque 创建一个双端队列
* 栈是LIFO,队列是FIFO
* 广度优先搜索时,对于检查过的人不能再去检查
1 # 广度优先搜索示例
2 from collections import deque
3
4 # 创建一个关系图(散列表)
5 graph = {}
6 # 单引号与双引号基本无使用上的区别,但是三引号可实现跨行输出
7 graph["you"] = ["alice", 'bob', "claire"]
8 graph["alice"] = ['peggy']
9 graph["bob"] = ["anuj", 'peggy']
10 graph['claire'] = ["thom", 'jonny']
11 graph["peggy"] = []
12 graph["anuj"] = []
13 graph["thom"] = []
14 graph["jonny"] = []
15
16
17 search_queue = deque()
18 search_queue += graph["you"]
19
20 # 判断是否为经销商
21 def person_is_seller(name):
22 return (name[-1] == 'o')
23
24 def search(search_queue):
25 searched = []
26 while search_queue:
27
28 person = search_queue.popleft() #取出队列左边第一个元素
29 # 检查后不再检查
30 if person not in searched:
31 if person_is_seller(person):
32 print(person + " is a mago seller !")
33 return True
34 else:
35 # 把TA的朋友加入搜索队列
36 search_queue += graph[person]
37 searched.append(person)
38 print("Can't find mago seller in your friends")
39 return False
40 search(search_queue)
Dijkstra算法
* 找出目前最便宜的节点
* 更新该节点的邻居的开销
* 重复这个过程,直到对图中所有节点都这么做了
* 计算最终路径
* Dijkstra算法只适用与有向无环图
* 对于包含负权边的图,请使用贝尔曼-福德算法graph
1 # Dijkstra算法
2
3 # 寻找lowest_cost_node
4 def find_lowest_cost_node(costs):
5 lowest_cost = float("inf")
6 lowest_cost_node = None
7 for node in costs:
8 cost = costs[node]
9 if cost < lowest_cost and node not in processed:
10 lowest_cost = cost
11 lowest_cost_node = node
12 return lowest_cost_node
13
14
15 # Create a graph
16 graph = {}
17 graph['start'] = {}
18 graph['start']['a'] = 6
19 graph['start']['b'] = 2
20 graph['a'] = {}
21 graph['a']['fin'] = 1
22 graph['b'] = {}
23 graph['b']['fin'] = 5
24 graph['b']['a'] = 3
25 graph['fin'] = {}
26
27
28 # create a cost dict
29 infinity = float('inf')
30 costs = {}
31 costs['a'] = 6
32 costs['b'] = 2
33 costs['fin'] = infinity
34
35 # creata a parent dict
36 parents = {}
37 parents['a'] = "start"
38 parents['b'] = "start"
39 parents['fin'] = None
40
41
42 # record processed nodes
43 processed = []
44
45
46 node = find_lowest_cost_node(costs)
47 while node is not None:
48 cost = costs[node]
49 neighbors = graph[node]
50 for n in neighbors.keys():
51 new_cost = cost + neighbors[n]
52 if costs[n] > new_cost:
53 costs[n] = new_cost
54 parents[n] = node
55 processed.append(node)
56 node = find_lowest_cost_node(costs)
57
58 route = ['fin']
59 node = parents['fin']
60 route.append(node)
61 node = parents[node]
62 route.append(node)
63 node = parents[node]
64 route.append(node)
65
66
67 print(route)
贪婪算法
* 衡量标准:速度有多快;得到的近似解与最优解的接近程度
* 易于实现,运行速度快
* 识别NP完全问题
* 随着元素的增加操作速度极速增加
* 涉及“所有组合”的问题通常是NP完全问题
* 问题可转换为集合覆盖问题和旅行商问题
原文出处:https://www.cnblogs.com/morvan/p/11940236.html
来源:oschina
链接:https://my.oschina.net/u/4277648/blog/3246118