V

算法可视化

ZHEN
分享到微博分享到 XGitHub 仓库个人主页
学习工具算法复杂度速查算法学习路径
数据结构数组链表栈队列树堆哈希表图字典树并查集LRU 缓存跳表线段树B+ 树布隆过滤器树状数组
经典排序算法冒泡排序鸡尾酒排序双调排序选择排序插入排序二分插入排序希尔排序归并排序自顶向下归并快速排序三路快排双轴快排堆排序计数排序基数排序桶排序
图算法Dijkstra 最短路Kruskal 最小生成树Prim 最小生成树Bellman-Ford 最短路拓扑排序Floyd 多源最短路强连通分量2-SAT最大流二分图匹配LCA 倍增欧拉路径
动态规划编辑距离0-1 背包完全背包最长公共子序列最长递增子序列硬币找零方案数石子合并旅行商 TSP树形 DP数位 DP换根 DP
回溯与搜索N 皇后子集生成全排列组合总和迷宫寻路岛屿数量单词搜索数独A* 寻路
字符串KMP 字符串匹配Rabin-KarpBoyer-MooreManacher后缀数组LCP / height 数组AC 自动机Z 函数
数学与数论埃氏筛线性筛欧几里得算法快速幂扩展欧几里得中国剩余定理欧拉函数米勒-拉宾FFTPollard's Rho
计算几何凸包旋转卡壳最近点对线段相交扫描线求交
查找二分查找二分边界旋转数组搜索二分答案三分查找

堆 Heap

数据结构 · 用数组装的完全二叉树(大顶堆)

什么是堆

堆还是一棵完全二叉树(从上到下、从左到右挨个填满,不留空),但它的规矩和 BST 不同:大顶堆要求每个父节点都 ≥ 它的孩子,所以堆顶永远是最大值。它不比较左右大小,只管父子。

最妙的是它不用指针、直接用一个数组装:下标 i 的左孩子是 2i+1、右孩子 2i+2、父亲是 ⌊(i-1)/2⌋。下面上下两个视图是同一个堆——上面是数组、下面是树。输入一个数插入,看它从末尾上浮到该去的位置。

亲手试试
数组
90
70
80
40
60
30
50
0
1
2
3
4
5
6
树(同一个堆)
90
70
80
40
60
30
50

输入一个数,点「插入」,看它从数组末尾上浮到位。

插入会先放到数组末尾(树的最后一个叶子),再一路和父亲比:比父亲大就交换、上浮,直到不再比父亲大。「弹出堆顶」则相反:取走最大的根,把末尾元素搬到根上,再和较大的孩子比、下沉归位。两步都只走一条到根的路径,所以是 O(log n)。这正是优先队列和堆排序的核心。

堆在哪里用

优先队列:任务调度、Dijkstra 最短路,每次 O(log n) 取最值。
堆排序:反复弹出堆顶,得到有序序列。
Top-K / 中位数:用堆维护最大/最小的若干个。

栈、队列、数组、链表、树、堆都讲完了,剩下两种更「跳跃」的结构——哈希表和图。