其他分享
首页 > 其他分享> > 排序相关

排序相关

作者:互联网

对于排序,绝大部分情况一发 \(sort\) 完事
这里记录一下不太常用的排序方法


冒泡排序

流程:每次扫描一遍数组,交换相邻两项,每次完成后确定一个数的位置
用途:冒泡排序多和逆序对、树状数组等结合,冒泡一次减少一个逆序对
复杂度:\(O(n^2);O(n)\)

再来通过例题理解一下冒泡排序的本质:


P4378 [USACO18OPEN]Out of Sorts S

要求冒泡排序的轮数,因为每次一个大数会往右移动很多,而小数最多只会往左移动一个
那么轮数即为往左移动的最长距离


P4375 [USACO18OPEN]Out of Sorts G

这次又变得不同了,那么寻找新的稳定变化量
可以发现,对于每个位置之前比它大的数的数量就是一个变化量
一个数列是有序的,当且仅当所有位置前边位置上的数没有比它大的
而题目的操作的本质是将一个大数拉到后面,再选择一个小数拉回来,那么每个位置前面的大数最多减一,那么答案即为每个位置前面大于它的个数


P4372 [USACO18OPEN]Out of Sorts P

情境再次变化,那么寻找新的变化量
发现一个数列是有序的,当且仅当它的每个空隙都成为一个“分隔点”
一个数不需要进行冒泡当且仅当两边都有序了,即两边成为分隔点的最大值
考虑一个分隔点出现的时间,因为一次冒泡把一个后面小的数移动到前面,那么答案为一个数后面最远的比这个数小的距离


插入排序

流程:每次插入一个数到应该的位置,将后面的瞬移
用途:维护凸包、多组询问等情境下可能有着更优秀的复杂度
复杂度:\(O(n^2);O(n)\)


归并排序

流程:采用分治的思想,每个小区间结束时变成有序,然后依次合并左右区间的数
用途:可以解决二维偏序问题
复杂度:\(O(nlogn);O(n)\)


选择排序

流程:每次扫描一遍数组,将最值与边上的数交换位置
用途:无
复杂度:\(O(n^2);O(n)\)


树形选择排序

流程:对选择排序进行优化,可以将其建成一棵二叉树,每个节点保存子树内的最值,那么根是最值。每次将最值的位置设为 \(inf\),然后将其所有祖先的值更新
用途:可能可以用于锦标赛类题
复杂度:\(O(nlogn);O(nlogn)\)


堆排序

流程:构建堆,每次取堆顶
用途:无
复杂度:\(O(nlogn);O(n)\)


快速排序

流程:已然采用分治的思想,每次随机区间内的一个点,将比这个数小的数放入左区间,大的放入右区间,递归处理
用途:例题(accoder上的,既然被 \(ban\) 了那就不放了)
复杂度:\(O(nlogn);O(n)\)


桶排序

流程:每个值域开一个桶,然后枚举值域顺次取出
用途:对于值域很小的题可以用来卡常
复杂度:\(O(n);O(v)\)


Median Game

一场比赛两道桶排这很不好,分别是维护中位数和最大值
注意许多情境下桶排的复杂度都依赖于数据随机


基数排序

流程:从小到大考虑数的每一位,对组内当前位进行排序
用途:相比于桶排序,可以进行多关键字排序
复杂度:\(O(d(n+v);O(v)\)


中位数相关

最经典的用途在于在一维坐标系上选择一个点使得到所有点距离最小,那么选择中位数时最小(这个问题在二维上就是经典的退火模板题——平衡点)


P5992 [PA2015]Rozstaw szyn

对于一堆点的最优值为中位数,但是可能会是一段区间
于是就造成了一堆区间的最优值是什么的问题
结论是把区间端点排序后的中位数
证明可以用类似于 \(+1\) \(-1\) 形成凸包的模型

标签:nlogn,复杂度,中位数,用途,相关,排序,流程
来源: https://www.cnblogs.com/yang-cx/p/15526508.html