快速排序以及 TopN 问题
快速排序
快速排序的划分函数
first element 划分
int Partition(std::vector<int> &data, int left, int right) {
int ret = left;
int pivot = data[left];
while (left < right) {
while (left < right && data[right] > pivot) {
--right;
}
while (left < right && data[left] <= pivot) { // 把 pivot 归到左半部分
++left;
}
if (left < right) {
swap(data[left], data[right]);
}
}
swap(data[left], data[ret]);
return left;
}
void QuickSort(std::vector<int> &data, int left, int right) {
if (right - left > 0) {
int i = Partition(data, left, right - 1);
QuickSort(data, left, i);
QuickSort(data, i + 1, right);
}
}
快速排序的时间复杂度
在理想情况下,每次 partition 都能平分 n 个元素,需要 lg(n) 次的划分,每一次划分都会遍历所有元素,所以时间复杂度为 O(nlgn),在基本有序情况下 partition 函数的时间复杂度为 O(n),划分会执行接近 n 次,所以时间复杂度为 O(n^2)。
快速排序的稳定性
[1,4,2(1),3,6,2(2),5,2(3)]
我们选择第二个 2 也就是 2(2) 为基准,一次partition后,2(3)与 4 交换了位置,得到
[1,2(3),2(1),2(2),6,3,5,4]
可见是不稳定的
如果一个数字在待排序的列表中出现三次或以上,而这个数字在列表中出现的(非首次和末次)一次被选为基准(pivot)则结果肯定是不稳定的。因此,通过更改比较时 >= 符号为 > 符号是没有意义的,因为不稳定的根源在于基准的选取。
如果要得到稳定的快速排序,必须在选取基准时避免这种情况,而且在交换元素时要小心不要打乱相同元素的相对顺序。一种可选的做法是先记录相同元素的相对位置,再进行排序。这需要额外的空间开销。
TopN 问题
由快速排序的过程可知,每次 partition 调用结束后,都能确定出一个元素的位置。所以如果使用从小到大的快速排序,那么第 k 大数,就出现在 pos = len - k 下标位置。所以有如下代码:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int res_pos = nums.size() - k;
QuickSort(nums, 0, nums.size(), res_pos);
return nums[res_pos];
}
int Partition(std::vector<int>& data, int left, int right) {
int ret = left;
int pivot = data[left];
while (left < right) {
while (left < right && data[right] > pivot) {
--right;
}
while (left < right && data[left] <= pivot) {
++left;
}
if (left < right) {
swap(data[left], data[right]);
}
}
swap(data[left], data[ret]);
return left;
}
void QuickSort(std::vector<int>& data, int left, int right, int k) {
if (right - left > 0) {
int i = Partition(data, left, right - 1);
if (i == k) {
return;
}
QuickSort(data, left, i, k);
QuickSort(data, i + 1, right, k);
}
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧