看完 react 的 diff 算法和 swagger 的数据结构,想温习波数据结构和算法。
2019-1-17 记
数组
最简单的内存数据结构。
栈
一种顺序数据结构
栈是一种遵从后进先出(LIFO)原则的有序集合。
新添加的或待删除的元素都保存在栈的末尾,称做栈顶,另一端就叫栈底。
在栈里,新元素都靠近栈顶,旧元素都接近栈底。
栈的创建
1 | function Stack() { |
从十进制到二进制
1 | function divideBy2(decNumber) { |
其他实例:平衡圆括号和汉诺塔
队列
一种顺序数据结构
队列是遵循 FIFO(First In First Out,先进先出,也称为先来先服务)原则的一组有序的项。
队列在尾部添加新元素,并从顶部移除元素。
最新添加的元素必须排在队列的末尾。
创建队列
1 | function Queue() { |
优先队列
1 | function PriorityQueue() { |
循环队列——击鼓传花
1 | function hotPotato(nameList, num) { |
链表
链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。
每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。
解决数组起点或中间插入或移除项的成本很高的问题
创建一个链表
1 | function LinkedList() { |
集合
一种非顺序数据结构
集合是由一组无序且唯一(即不能重复)的项组成的。
集合中的对象列表用{}(大括号)包围。
创建一个集合
1 | function Set() { |
字典和散列表
字典
一种非顺序数据结构
在字典中,存储的是[键,值]对,其中键名是用来查询特定元素的。
字典和集合很相似,集合以[值,值]的形式存储元素,字典则是以[键,值]的形式来存储元素。
字典也称作映射。
创建一个字典
1 | function Dictionary() { |
散列表
一种非顺序数据结构
散列表就是通过散列算法将字典的键转化成对应下标值取得键对应的值。
散列算法的作用是尽可能快地在数据结构中找到一个值。
创建一个散列表
1 | function HashTable() { |
树
一种非顺序数据结构
它对于存储需要快速查找的数据非常有用。
创建 BinarySearchTree 类
1 | function BinarySearchTree() { |
图
一种非线性数据结构。
图是网络结构的抽象模型。
创建图类
1 | function Graph() { |
排序和搜索算法
排序算法:冒泡排序、选择排序、插入排序、归并排序、快速排序
搜索算法:顺序搜索、二分搜索
1 | function ArrayList() { |
算法补充知识
递归
递归是一种解决问题的方法,它解决问题的各个小部分,直到解决最初的大问题。
通常涉及函数调用自身。
动态规划
动态规划(Dynamic Programming,DP)是一种将复杂问题分解成更小的子问题来解决的优化技术。
用动态规划解决问题时,要遵循三个重要步骤:
- 定义子问题;
- 实现要反复执行而解决子问题的部分(这一步要参考前一节讨论的递归的步骤);
- 识别并求解出边界条件。
能用动态规划解决的一些著名的问题如下:
- 背包问题:给出一组项目,各自有值和容量,目标是找出总值最大的项目的集合。这个
问题的限制是,总容量必须小于等于“背包”的容量。 - 最长公共子序列:找出一组序列的最长公共子序列(可由另一序列删除元素但不改变余
下元素的顺序而得到)。 - 矩阵链相乘:给出一系列矩阵,目标是找到这些矩阵相乘的最高效办法(计算次数尽可
能少)。相乘操作不会进行,解决方案是找到这些矩阵各自相乘的顺序。 - 硬币找零:给出面额为 d1…dn 的一定数量的硬币和要找零的钱数,找出有多少种找零的
方法。 - 图的全源最短路径:对所有顶点对(u, v),找出从顶点 u 到顶点 v 的最短路径。
贪心算法
贪心算法遵循一种近似解决问题的技术,期盼通过每个阶段的局部最优选择(当前最好的解),从而达到全局的最优(全局最优解)。
大 O 表示法
描述算法的性能和复杂程度。
O(1):常数的
O(log(n)):对数的
O((log(n))c):对数多项式的
O(n):线性的
O($n^2$):二次的
O($n^c$):多项式的
O($c^n$):指数的