排序
筱竹&XZ
这个作者很懒,什么都没留下…
展开
-
洛谷 P3183 [HAOI2016]食物链(记忆化搜索/拓扑排序)
物种的名称从 1 到 n 编号, M 条能量流动关系形如 a1→b1,a2→b2,a3→b3⋯am−1→bm−1,am→bm 其中 ai→bi 表示能量从物种 ai 流向物种 bi ,注意单独的一种孤立生物不算一条食物链。如果有若干条边 u1→v,u2→v,⋯uk→v ,那么只有当 f[u1],f[u2],⋯,f[uk] 全部计算完成时,才可以计算 f[v]。也即, DAG 中的有向边规定了计算的顺序,只有当一个点的所有前驱点都计算完成时,该点才可以计算。原创 2024-09-01 15:30:00 · 352 阅读 · 0 评论 -
拓扑排序(c++)
观察上图可以发现,有一条 1→2 的有向边,表示 2 进入队列之前需要先让 1 进入队列。拓扑排序就是依照这个原理进行的,但是拓扑排序将这个判断过程简化为了对入度的判断。通过只判断入度,可以在保证正确性的情况下简化算法流程。通过上面的判断方式,我们发现可以根据一个点的入边来判断这个点进入队列前需要哪些点已经进入队列。这一名词,实际上拓扑序的定义与题目要求的排队序列定义相同,就是指满足该图要求的一种序列。所以,拓扑排序不仅可以用于求解拓扑序,也可以用于判断一个有向图中是否存在有向环。原创 2024-08-30 14:19:50 · 674 阅读 · 0 评论 -
归并排序 -- 稳定(c++)
方法很简单,用两个变量p1和p2分别表示两个数组未被取出的元素中最小元素的下标,初始为 0。然后每次取出a[p1]和b[p2]中较小的那个放进新的数组里。如果取出的是a[p1],那p1就自增 1;否则,把区间划分为 [l,mid] 和 [mid+1,r] 两部分递归处理,其mid=⌊2l+r⌋。归并排序的基本思想是分治,每次把待排序的区间分成两半,递归地处理。先来看这样一个问题,现在你有两个有序数组a和b,如何把他们合并为一个新的有序数组c?如果有数组被取空了,那就把另一个数组剩下的都放进来就可以了。原创 2024-05-02 14:52:19 · 25 阅读 · 1 评论 -
插入排序--稳定(c++)
插入排序是一种非常直观的排序算法,它的基本思想是将数组分为已排序的前半部分和待排序的后半部分,每次把待排序部分的第一个元素,插入到已排序部分的对应位置中,直到全部记录都插入到已排序部分中。上述代码中,内层循环是从大到小找第一个 aj≥ai 的位置 j,然后把 ai 放在 j+1 这个位置。我们边寻找,边调整元素的位置,相当于提前了元素后移的操作。因此一次插入的时间复杂度为 O(n),一共执行 n−1 次,总时间复杂度为 O(n2)。显然,插入排序是一种稳定的排序方法。原创 2024-05-01 20:20:42 · 314 阅读 · 0 评论 -
选择排序--不稳定(c++)
选择排序的思想是,将数组分为已排序的前半部分和待排序的后半部分,每趟从待排序区域选取最小的元素,将其放到已排序区域的最后。因为每趟可以让待排序区域的元素数量减少一个,所以总共需要 n−1 趟操作就可以将整个数组排序完成。很显然,选择排序的时间复杂度也是 O(n2)。为最后的交换操作可能会破坏原来值相同的元素顺序,因此选择排序是不稳定的排序算法。原创 2024-05-01 20:25:06 · 305 阅读 · 0 评论 -
冒泡排序 -- 稳定(c++)
冒泡排序的基本思想为:假如待排序数组的长度为 n,从前往后两两比较相邻元素的关键字,若 ai−1>ai,则交换它们,直到数组比较完成。每趟交换以后最后一个元素一定是最大的,不再参与下一趟交换。也就是对于第 i 趟交换,只需要比较到 an−i 即可。直到一趟比较内没有进行交换,算法结束。时间复杂度也为O(n2)。冒泡排序是一种稳定的排序算法。原创 2024-05-02 10:46:58 · 42 阅读 · 1 评论