算法图解 读书笔记(上)
最近看了一本算法入门书——算法图解。
封面的插画很好玩儿。最吸引我的还是封面里的一句话:向小说一样有趣的算法入门书。
上个封面,大家感受一下:
一、算法简介
1.1 二分查找
一个有序数组中找一个数的位置(对应该数字所在数组下标index)
def binary_search(list, item):low = 0high = len(list) - 1while low <= high:mid = int((low + high) / 2)guess = list[mid]if guess == item:return midif guess > item:high = mid - 1else:low = mid + 1return Nonemy_list = [1, 3, 5, 7, 9]print(binary_search(my_list, 3)) # => 1
print(binary_search(my_list, -1)) # => None
- 也可用递归实现
- 操作对象:数组
- 使用前提:有序的数组
- 性能方面:时间复杂度O(logn)
1.2 旅行商问题
旅行商前往n个城市,确保旅程最短。求可能的排序:n!种可能。
二、选择排序
2.1 数组和链表
- 数组:连续存储在硬盘中;
- 链表:分散存储在硬盘中;
2.2 选择排序
将数组元素按照从小到大的顺序排序,每次从数组中取出最小值
def findSmallest(arr):smallest = arr[0]smallest_index = 0for i in range(1, len(arr)):if arr[i] < smallest:smallest = arr[i]smallest_index = ireturn smallest_indexdef selectionSort(arr):newArr = []for i in range(len(arr)):smallest = findSmallest(arr)newArr.append(arr.pop(smallest))return newArrprint(selectionSort([5, 3, 6, 2, 10])) #[2, 3, 5, 6, 10]
三、递归 一种优雅的问题解决方法
适用递归的算法要满足:
- 基限条件(即返回的条件)
- 递归条件(调用递归函数)
特点:
- 自己调用自己,调用栈在内存叠加,如果没有返回条件,将无限循环调用,占用大量内存,最终爆栈终止进程。
还有一种高级一点的递归:
- 尾递归 (将结果也放入函数参数,内存里面调用栈只有一个当前运行的函数进程)
举个简单的例子: 阶乘f(n) = n!
#递归
def fact(x): if x == 1:return 1else:return x * fact(x-1) #注意这里跟尾递归不同#尾递归
def factorial(x,result): if x == 1:return resultelse:return factorial(x-1,x*result)if __name__ == '__main__':print(fact(5)) #5*4*3*2*1 = 120print(factorial(5,1)) #120
四、快速排序 (分而治之策略)
快速排序
def quicksort(array):if len(array) < 2:return arrayelse:pivot = array[0]less = [i for i in array[1:] if i <= pivot]print(less)greater = [i for i in array[1:] if i > pivot]print(greater)return quicksort(less) + [pivot] + quicksort(greater)if __name__ == '__main__':print(quicksort([7,1,10,5,3,2,6]))
- 每次选取数组中一个元素x当作分水岭
- [小于元素x的数组] + [x] + [大于元素x的数组]
- 然后递归调用,直到最后处理的数组元素只剩下零个或者一个
- 平均时间复杂度O(nlogn)
- 最差情况时间复杂度O(n^2)
- 出现最差情况是:快排的数组本来就是有序的(顺序/倒序),选取的元素又是开头第一个的话,每次变成只能处理一侧的数组。 改善:可以选取数组中间的元素当作分水岭pivot,只有两边的元素就都能均匀处理了。
归并排序
def mergeSort(array):if len(array) < 2:return arrayelse:mid = int(len(array)/2)left = mergeSort(array[:mid])right = mergeSort(array[mid:])return merge(left, right)def merge(left, right): #并两个已排序好的列表,产生一个新的已排序好的列表result = [] # 新的已排序好的列表i = 0 # 下标j = 0# 对两个列表中的元素 两两对比# 将最小的元素,放到result中,并对当前列表下标加1while i < len(left) and j < len(right):if left[i] <= right[j]:result.append(left[i])i += 1else:result.append(right[j])j += 1# 此时left或者right其中一个已经添加完毕,剩下的就全部加到result后面即可 result += left[i:] result += right[j:]return resultarray = [9,5,3,0,6,2,7,1,4,8]
result = mergeSort(array)
print('排序后:',result) #排序后: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
归并排序时间复杂度是O(nlogn)
最坏情况也是O(nlogn)
归并排序采用先分后总的方式,先按中间分,分到数组最后只有一个元素为止,最后两两合并。有点mapReduce的味道。
冒泡排序
#冒泡排序,每次寻找最小到元素往前排,就像汽水从下往上冒一样。所以叫冒泡排序
def simpleSort(array):for i in range(len(array)-1):for j in range(i,len(array)):if array[i] > array[j]:temp = array[i]array[i] = array[j]array[j] = tempreturn arrayprint(simpleSort([9,8,6,7,4,5,3,11,2]))
- 冒泡排序时间复杂度O(n^2)
- 两个for循环搞定,每一轮for循环找到一个最小值。for循环两两元素对比交换
算法图解 读书笔记(上)相关推荐
- 算法图解读书笔记:附程序
算法图解通俗易懂,下面是随书练习程序,基于python3 二分法 #二分法 def binary_search(list, item):low = 0high = len(list)-1while l ...
- 算法图解——读书笔记06
广度优先搜索 首先,先介绍一下什么是图(它们不涉及X轴和Y轴),再介绍第一种图算法--广度优先搜素(breadth-frist search,BFS). 广度优先搜素让你能够找出两样东西之间的最短距离 ...
- 算法导论读书笔记(8)
算法导论读书笔记(8) 目录 计数排序 计数排序的简单Java实现 基数排序 基数排序的简单Java实现 桶排序 计数排序 计数排序 假设 n 个输入元素中的每一个都是介于0到 k 之间的整数,此处 ...
- 算法导论读书笔记(7)
算法导论读书笔记(7) 目录 快速排序 快速排序的简单Java实现 快速排序的性能 最坏情况划分 最佳情况划分 快速排序的随机化版本 比较排序 快速排序 快速排序是一种原地排序算法,对包含 n 个数的 ...
- 算法导论读书笔记(19)
http://www.cnblogs.com/sungoshawk/p/3802553.html 算法导论读书笔记(19) 目录 最优二叉搜索树 步骤1:一棵最优二叉查找树的结构 步骤2:一个递归解 ...
- Maltab在数学建模中的应用(第二版)——读书笔记上
Maltab在数学建模中的应用(第二版)--读书笔记上 1.MATLAB与数据文件的交互 1.1数据拟合 1.2数据拟合实例 1.3数据可视化 1.4层次分析法 2.规划问题的MATLAB求解(多约束 ...
- 《BIG DATA大数据日知录 架构和算法》读书笔记
2019独角兽企业重金招聘Python工程师标准>>> <BIG DATA大数据日知录 架构和算法>读书笔记 博客分类: 架构 分布式计算 1.数据分片和路由 Hash ...
- 《漫画算法》读书笔记
<漫画算法>读书笔记 在图书馆借阅算法书时,看到了一本非常吸引我的算法书--<漫画算法>.算法还能以漫画的方式展示出来吗?我带着我的疑惑翻开了这本书,里面的语言非常接地气,通俗 ...
- 重构机器学习算法的知识体系 - 《终极算法》读书笔记
2019独角兽企业重金招聘Python工程师标准>>> 最近有幸从图书馆借阅了Pedro Domingos的<The Master Alogrithm>一书,这本书的中文 ...
最新文章
- 腾讯 Robotics X 实验室首次「开箱」移动机器人,能走梅花桩,还能自平衡
- MySQL删除用户权限(REVOKE)
- 提高方面级情感分析的性能:一种结合词汇图和句法图的方法
- MySQL事务及锁机制大揭秘 - 公开课笔记
- POJ 3259 SPFA
- word中图片超出页边距_如何在Word中更改页边距
- HTML如何添加锚点,干货满满
- Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - SSE扩展(10) - MXCSR状态控制指令
- mysql like反义_MySQL条件检索_WHERE
- mysql多库备份_Mysql 之多库备份
- 在 Vue 中是使用插槽
- BZOJ 1002: [FJOI2007]轮状病毒【生成树的计数与基尔霍夫矩阵简单讲解+高精度】
- 机器学习教程之语义分割入门教程
- 麒麟 linux下安装显卡驱动,中标麒麟7安装英伟达显卡驱动过程简述
- 微信会员卡 java请求_会员系统对接微信会员卡的好处
- 用新开放的 notion api 结合 python 爬虫搞个羊毛线报页面
- 修改了便签内容怎样再恢复?
- 下载原版百度文库资料
- HTML label标签介绍
- 北漂码农的真实心声:赚一线城市的钱,还二线城市的房贷