列表
二分查找
分块查找
散列查找
除留余数法
直接定址法
数字分析法
手机号码用后四位散列,虽然前三位的分布差异性很大,但是后四位的分布是均匀的
用后四位作为散列函数的关键字
平方取中法
拉链法
开放定址法-线性探测法
删除一个元素,要标记这个位置已删除
开放定址法-平方探测法
开放定址法-伪随机序列法
伪随机序列法很宽泛,随便取di,只要有一套规则就行
再散列法
树
路径:只能从上往下
平衡二叉树
线索二叉树
:除了名字唬人,没什么难的
树的存储-双亲表示法
:parent没必要取-1,直接用无符号整型从0开始不也一样,还节约存储空间。
带权路径长度
哈夫曼树
并查集(2022)
红黑树(2022)
黑高度:对每个结点,从该结点到任一叶结点的简单路径上,所含黑结点的数目
路径是从上向下的
红黑树任意结点左右子树高度差不超过2倍:假如左子树有一个黑,那么右子树最多放红黑红,右子树是左子树的三倍,也就是高度差为2倍
生成树
连通图的子图,边数量最少,能连接所有顶点
非连通图的子图,边数量最少,能连接所有顶点
二叉排序树
中序遍历可以得到递增序列
被删除结点的右子树中序遍历的第一个结点就是右子树的最小值结点
同理也可以用被删除结点的左子树的最大值来替代这个结点
查找长度
平均查找长度 ASL
把树里的每个结点都查找一次,取平均
B树 (多路平衡查找树)
所有子树高度相同,失败结点都在同一层
插入
关键字数达到上限,需要分裂成两个
上文的孩子其实指的是分叉数,分叉数是阶数,是关键字数-1
删除
B+树
图
邻接矩阵存带权图
十字链表存带权图
邻接多重表
不像邻接表和邻接矩阵那样,维护两份冗余数据
连通分量
上图连通分量为2
广度优先搜索复杂度
深度优先搜索复杂度
最小生成树
Prim算法
Kruskal 克鲁斯卡尔算法
最短路径问题
单源最短路径 BFS算法
单源最短路径就是从一个固定的起点出发,计算到各个其他顶点的最短路径
单源最短路径 Dijkstra算法
BFS算不了带权的
所有顶点间的最短路径 Floyd算法
就是说,在最短路径长度矩阵中,选择v0作为中转点,那么v0这一行和这一列就不用管了,剩下的部分组成一个n-1阶方阵,去处理这个方阵的值
核心代码简单,k就是选取的中转点
A[i][j]就是从i到j的距离
Floyd算法可以解决负权值的问题,Dijkstra不行
有向无环图 DAG
描述表达式
对AOV网进行拓扑排序
对图进行拓扑排序,就是不断删除入度为0的顶点,
环路中的顶点在这个算法中,不会入度降到0,所以存在环路时count计算出的顶点数量只会小于总顶点数量
对AOV网进行逆拓扑排序
和拓扑排序很像,每次删除出度为0的点
图的存储结构使用逆邻接表
使用邻接表的话需要用DFS算法
AOE网
知识点:关键路径
AOE网感觉就是流程图
一维排序
插入排序
折半插入排序
mid=( low + high )/ 2
就是向下取整
第二轮迭代:
取右侧 low2= mid1 + 1
为了保证稳定性,
待插入元素小于mid元素,放左边;
待插入元素大于等于mid元素,放右边。
链表插入排序
希尔排序
局部有序到全局有序
交换排序-冒泡排序
交换次数为0,提前结束
交换排序-快速排序
- 哪个指针指空,另一个指针移动,直到有满足放入条件的数据
- 把数据放入指向空的指针,另一个指针此时变为空指针,循环上一步
这里是选取第一个元素作为枢轴,
2023年408是选取任意一个元素作为枢轴,取出来,
那么就要把第一个位置空出来,其他位置往后移补上枢轴位置的空缺,然后让low指向第一个位置(此时为空)
选择排序-简单选择排序
我觉得:不特定位置的交换基本上都会导致不稳定
选择排序-堆排序
堆的建立
从后往前遍历所有的非终端结点,比较左右孩子,把符合条件的换上来(有就比较,没有就不比较)
如果下坠的位置是非终端结点,那么还得再检查要不要继续下坠
继续下坠的过程其实可以用递归写,没必要都写到这个函数里面
基于已建立的堆进行排序
把堆顶元素与最后一个元素交换,然后把前面n-1个元素重新建立新的堆(实际上前n-1个元素重新建立堆,除了堆顶元素不一定满足堆的条件,其他元素都满足,只需要将堆顶元素下坠即可)
下坠的时间复杂度o(logn)比建立堆的复杂度o(n)要低
建立初始堆的复杂度是o(n)
建立初始堆之后,只需要对其他n-1个结点换位后进行下坠即可
也就是o(nlogn)的复杂度
这个例子其实不够形象,
其实只要看全部都是相同的堆元素
a1=a2=a3
在建立堆之后,顺序一定不会变化
但是在堆排序之后,第一步就发生了变化,把a1放到了最后面
变成a3,a2,a1
然后第二轮排序,又变成了,a2,a3,a1
然后最终结果就是a2,a3,a1
可见堆排序最终的稳定性是夸张的差,每一个元素都不在它原本的相对位置了。
堆的插入
插入到最后位置,然后一路上升
堆的删除
堆底元素替代,然后一路下坠
这里王道讲错了,堆只能删除堆顶元素,不是删除任意元素
以下是浙大的慕课
CSDN博客中也有其他人说,删除堆是删除堆顶的数据,将堆顶的数据与最后一个数据一换,然后删除数组最后一个数据,再进行向下调 整算法。
归并排序
代码是二路归并的实现
用三个指针,把顺序表划分为两个用于归并的序列
实现稳定性:两个归并序列有相等的元素,优先使用左边的
基数排序
没有比较关键字的大小
外部排序
需要排序的数据量太大
无法全部读入内存,所以需要用外部排序
使用归并排序方法
用两个输入缓冲区读取的数据,进行归并排序后,
得到的长数据,切分后存回这两个输入缓冲区
然后依次放入输出缓冲区,写回
多路平衡归并-败者树
堆顶元素出堆,然后新的元素加入,一路上升,然后继续堆顶元素出堆
置换-选择排序
之前的初始归并段大小只能和内存工作区相同
现在要把初始归并段大小大于内存工作区
先把记录放入内存工作区
一边读一边输出有序的归并段
如果内存工作区的所有元素都无法输出有序归并段
就另开一个新的归并段
一次会从外存读入多个记录,但是只移入一个到内存工作区
最佳归并树
多路归并的情况,就是构造多路哈夫曼树
最小的n个结点组成新结点
kn_k = n - 1 就是除了根结点以外的结点,都在分叉上,能分叉的只有k度结点,所以分叉n-1次