什么是算法和数据结构?你可能会在一些教材上看到这句话:
程序 = 算法 + 数据结构
算法(Algorithm):是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。
数据结构(Data Structures):是计算机存储和组织数据的一种方式,可以用来高效地处理数据。
举个例子:二分查找就是一个非常经典的算法,而二分查找经常需要作用在一个有序数组上。这里二分就是一种折半的算法思想,而数组是我们最常用的一种数据结构,支持根据下标快速访问。很多算法需要特定的数据结构来实现,所以经常把它们放到一块讲。
实际上,在真正的项目开发中,大部分时间都是 从数据库取数据 -> 数据操作和结构化 -> 返回给前端,在数据操作过程中需要合理地抽象,组织、处理数据,如果选用了错误的数据结构,就会造成代码运行低效。这也是我们需要学习算法和数据结构的原因。
笨方法学算法这里我们用一种很原始的『笨』方法来学习算法:纸笔模拟。
阅读资料了解算法思想
纸笔模拟尝试理解
用自己熟 ...
基本排序算法从本章开始讲常见的基于比较的排序算法,先讲三个简单的但是时间复杂度却不太理想的排序算法,包括冒泡排序、选择排序和插入排序。
冒泡排序bubble sort 可以说是最简单的一种排序算法了,它的思想如下。对一个数组进行 n-1 轮迭代,每次比较相邻两个元素,如果相邻的元素前者大于后者,就交换它们。因为直接在元素上操作而不是返回新的数组,所以是一个 inplace 的操作。这里冒泡的意思其实就是每一轮冒泡一个最大的元素就会通过不断比较和交换相邻元素使它转移到最右边。
你可以想象假如有 10 个小盆友从左到右站成一排,个头不等。老师想让他们按照个头从低到高站好,于是他开始喊口号。每喊一次,从第一个小盆友开始,相邻的小朋友如果身高不是正序就会两两调换,就这样第一轮个头最高的排到了最右边。(冒泡到最右边)第二轮依次这么来,从第一个小朋友开始两两交换,这样次高的小盆友又排到了倒数第二个位置。依次类推。
我们在视频里手动模拟下它的过程。
import randomdef bubble_sort(seq): # O(n^2), n(n-1)/2 = 1/2(n^2 + n) n = ...
查找查找可以说是我们业务代码里用得最多的操作,比如我们经常需要在一个列表里找到我们需要的一个元素,然后返回它的位置。其实之前我们介绍的哈希表就是非常高效率的查找数据结构,很明显地它是用空间换时间。这一节介绍两个基本的基于线性结构的查找。
线性查找线性查找就是从头找到尾,直到符合条件了就返回。比如在一个 list 中找到一个等于 5 的元素并返回下标:
number_list = [0, 1, 2, 3, 4, 5, 6, 7]def linear_search(value, iterable): for index, val in enumerate(iterable): if val == value: return index return -1assert linear_search(5, number_list) == 5
是不是 so easy。当然我们需要来一点花样,比如传一个谓词进去,你要知道,在 python 里一切皆对象,所以我们可以把函数当成一个参数传给另一个函数。
def linear_search_v2(predi ...
字典 dict上一章我们介绍了哈希表,其实 python 内置的 dict 就是用哈希表实现的,所以这一章实现 dict 就非常简单了。当然 cpython 使用的是 c 语言实现的,远比我们写的复杂得多 (cpython/Objects/dictobject.c)。上一章我们用 python 自己写的一个 Array 来代表定长数组,然后用它实现的 HashTable,它支持三个最基本的方法
add(key ,value): 有 key 则更新,否则插入
get(key, default=None): 或者 key 的值,不存在返回默认值 None
remove(key): 删除一个 key,这里其实不是真删除,而是标记为 Empty
字典最常使用的场景就是 k,v 存储,经常用作缓存,它的 key 值是唯一的。内置库 collections.OrderedDict 还保持了 key 的添加顺序,其实用我们之前实现的链表也能自己实现一个 OrderedDict。
实现 dict ADT其实上边 HashTable 实现的三个基本方法就是我们使用字典最 ...
集合 set集合是一种不包含重复元素的数据结构,经常用来判断是否重复这种操作,或者集合中是否存在一个元素。这一章讲集合,实际上它的底层也是哈希表实现的,所以像实现 DictADT 一样,借助 HashTable 实现它也比较简单。
集合操作集合可能最常用的就是去重,判断是否存在一个元素等,但是 set 相比 dict 有更丰富的操作,主要是数学概念上的。如果你学过《离散数学》中集合相关的概念,基本上是一致的。 python 的 set 提供了如下基本的集合操作,假设有两个集合 A,B,有以下操作:
交集: A & B,表示同时在 A 和 B 中的元素。 python 中重载 __and__ 实现
并集: A | B,表示在 A 或者 B 中的元素,两个集合相加。python 中重载 __or__ 实现
差集: A - B,表示在 A 中但是不在 B 中的元素。 python 中重载 __sub__ 实现
对称差: A ^ B,返回在 A 或 B 但是不在 A、B 中都出现的元素。其实就是 (A|B) - (A&B), python 中重载 __xor__ 实现
...
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
Quick StartCreate a new post$ hexo new "My New Post"
More info: Writing
Run server$ hexo server
More info: Server
Generate static files$ hexo generate
More info: Generating
Deploy to remote sites$ hexo deploy
More info: Deployment