《算法图解》算法实现
最近学习《算法图解》,记录一下自己默写的代码和算法,用Python书写。
二分查找:
def binary_search(list,item): low = 0 high = len(list) - 1 while low <= high: mid = (int)((low + high) / 2) guess = list[mid] if guess == item: return mid elif guess > item: high = mid -1 else: low = mid + 1 return None my_list = [1,3,5,7,9] print(binary_search(my_list,5)) print(binary_search(my_list,10))
选择排序:
def findSmallest(arr): smallest = arr[0] smallest_index = 0 for i in range(1,len(arr)): if arr[i] < smallest: smallest = arr[i] smallest_index = i return smallest_index def selectionSort(arr): newArr = [] while len(arr) != 0: index = findSmallest(arr) newArr.append(arr.pop(index)) return newArr print(selectionSort([5,3,6,2,10]))
递归:
def factorial(x): if x == 1: return x else: return x * factorial(x-1) print(factorial(5))
D&C:
1.求和
arr = [1,3,5,7,9] def sum(arr): if len(arr) == 1: return arr[0] else: return arr[0] + sum(arr[1:]) print(sum(arr))
2.计数
arr = [1,3,5,7,9] def count(list): if list == []: return 0 else: return 1 + count(list[1:]) print(count(arr))
3.求最大值
def getMaxValue(arr): if len(arr) == 1: return arr[0] else: newArr = arr.copy() item = newArr.pop(0) if item > getMaxValue(newArr): return item else: return getMaxValue(newArr) arr = [4,8,9,2,3,3,10,8,4,1] print(getMaxValue(arr))
4.求最大值简化版
def getMaxValue(arr): if len(arr) == 1: return arr[0] else: return arr[0] if arr[0] > getMaxValue(arr[1:]) else getMaxValue(arr[1:]) arr = [4,8,9,2,3,3,10,8,4,1] print(getMaxValue(arr))
快速排序:
def quickSort(arr): if(len(arr) < 2): return arr else: pivot = arr[0] less = [i for i in arr[1:] if i <= pivot] greater = [i for i in arr[1:] if i > pivot] return quickSort(less) + [pivot] + quickSort(greater) arr = [10,5,2,3] print(quickSort(arr))
散列表:
voted = {} def check_voter(name): if voted.get(name): print('kick them out') else: voted[name] = True print('let them vote') check_voter('lyh') check_voter('zgf') check_voter('zgf')
广度优先搜索(Breadth First Search):
graph = {} graph['you'] = ['Bob','Alice','Claire'] graph['Bob'] = ['Anuj','Peggy'] graph['Alice'] = ['Peggy'] graph['Claire'] = ['Thom','Jonny'] graph['Peggy'] = [] graph['Thom'] = [] graph['Jonny'] = [] graph['Anuj'] = [] def is_mango_seller(name): if name[-1] == 'm': print(name + ' is a mango seller!') return True else: return False from collections import deque def search(name): search_queue = deque() search_queue += graph[name] searched = [] while search_queue is not None: man = search_queue.popleft() if man not in searched: if is_mango_seller(man): return True else: search_queue += graph[man] searched.append(man) search('you')
狄克斯特拉算法:
graph = {} infinity = float('inf') graph['start'] = {} graph['start']['a'] = 5 graph['start']['b'] = 2 graph['a'] = {} graph['a']['c'] = 4 graph['a']['d'] = 2 graph['b'] = {} graph['b']['a'] = 8 graph['b']['d'] = 7 graph['c'] = {} graph['c']['fin'] = 3 graph['c']['d'] = 6 graph['d'] = {} graph['d']['fin'] = 1 graph['fin'] = {} costs = {} costs['a'] = 5 costs['b'] = 2 costs['c'] = infinity costs['d'] = infinity costs['fin'] = infinity parents = {} parents['a'] = 'start' parents['b'] = 'start' parents['c'] = None parents['d'] = None parents['fin'] = None processed = [] def find_lowest_cost_node(costs): lowest_cost = infinity lowest_cost_node = None for node in costs: if costs[node] < lowest_cost and node not in processed: lowest_cost = costs[node] lowest_cost_node = node return lowest_cost_node node = find_lowest_cost_node(costs) while node is not None: cost = costs[node] neighbors = graph[node] for n in neighbors.keys(): new_cost = cost + neighbors[n] if new_cost < costs[n]: costs[n] = new_cost parents[n] = node processed.append(node) node = find_lowest_cost_node(costs) print(parents) arr = [] key = parents['fin'] while key != 'start': arr.append(key) key = parents[key] arr.reverse() print('最短路径为:start',end='') for i in arr: print('-'+i,end='') print('-fin') print('最短路径的花费为:' + str(costs['fin']))
贪婪算法:
states_needed = set(['wa','mt','id','or','nv','ut','ca','az']) stations = {} stations['kone'] = set(['id','nv','ut']) stations['ktwo'] = set(['wa','id','mt']) stations['kthree'] = set(['or','nv','ca']) stations['kfour'] = set(['nv','ut']) stations['kfive'] = set(['ca','az']) final_stations = set() while states_needed: best_station = None states_covered = set() for station,states in stations.items(): states_cover = states & states_needed if(len(states_covered) < len(states_cover)): best_station = station states_covered = states_cover states_needed -= states_covered final_stations.add(best_station) print('最终选择的站点为:',end='') print(final_stations)
动态规划算法:
1.背包问题
weight = [3,1,2,2,1] value = [10,3,9,5,6] things = ['水','书','食物','夹克','相机'] backpack_column = 6 weight.insert(0,0) value.insert(0,0) things.insert(0,'') rows = len(things) columns = backpack_column + 1 dp = [None] * rows for i in range(rows): dp[i] = [0] * columns dp_things = [None] * rows for i in range(rows): dp_things[i] = [''] * columns for i in range(1,rows): for j in range(1,columns): dp[i][j] = dp[i-1][j] if j >= weight[i]: currentValue = value[i] + dp[i-1][j - weight[i]] dp[i][j] = max(dp[i][j], currentValue) if dp[i][j] != currentValue: dp_things[i][j] = dp_things[i-1][j] else: dp_things[i][j] = things[i] + ' ' + dp_things[i-1][j - weight[i]] print('最大价值为:',end='') print(dp[i][j]) print('需要携带的东西为:',end='') print(dp_things[i][j])
2.最长公共子串
str1 = 'blue' str2 = 'clues' len1 = len(str1) len2 = len(str2) cell = [None] * len1 for i in range(len1): cell[i] = [0] * len2 maxVal = 0 for i in range(len1): for j in range(len2): if str1[i] == str2[j]: cell[i][j] = cell[i-1][j-1] + 1 else: cell[i][j] = 0 maxVal = max(maxVal,cell[i][j]) print('最长公共子串的长度为:',end='') print(maxVal)
3.最长公共子序列
compareStr = 'fosh' str1 = 'fort' str2 = 'fish' def compareStrMethod(s1,s2): cell = [None] * len(s1) for i in range(len(s1)): cell[i] = [0] * len(s2) maxVal = 0 for i in range(len(s1)): for j in range(len(s2)): if s1[i] == s2[j]: cell[i][j] = cell[i-1][j-1] + 1 else: cell[i][j] = max(cell[i-1][j], cell[i][j-1]) maxVal = max(maxVal,cell[i][j]) print('最长公共子序列的长度为:',end='') print(maxVal) compareStrMethod(compareStr,str1) compareStrMethod(compareStr,str2)
K最近邻算法(KNN算法):
record = [[5,1,0,300],[3,1,1,225],[1,1,0,75],[4,0,1,200],[4,0,0,150],[2,0,0,50]] param = [4,1,0] k = 4 paramLen = len(param) recordLen = len(record) import math def getDistance(a,b): sumVal = 0 for i in range(paramLen): sumVal += (a[i] - b[i]) ** 2 res = math.sqrt(sumVal) return res distances = [] for i in range(len(record)): entry = dict() entry['distance'] = getDistance(param,record[i]) entry['index'] = i distances.append(entry) for i in range(recordLen): for j in range(1,recordLen): if distances[j-1]['distance'] > distances[j]['distance']: temp = distances[j] distances[j] = distances[j-1] distances[j-1] = temp sumVal = 0 for i in range(k): index = distances[i]['index'] sumVal += record[index][paramLen] average = sumVal / k print('今天要烤的面包数为:',end='') print(average)
map和reduce的使用:
arr = [1,3,5,7,9] mapArr = map(lambda x:x * 2,arr) print('经过map函数后为:',end='') print(list(mapArr)) import functools reduceRes = functools.reduce(lambda x,y:x + y,arr) print('经过reduce函数后为:',end='') print(reduceRes)