快速排序是一种高效的排序算法,采用分治法的策略,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序的基本思想
快速排序的基本思想是选择一个基准元素(base),通常选择第一个或最后一个元素,然后对数组进行分区操作,使得:
-
比基准元素小的元素都移到基准的左边
-
比基准元素大的元素都移到基准的右边 这个过程称为一趟快速排序。
以下是按原理写的代码
#include <bits/stdc++.h>
using namespace std;
int n;
int a[100100] = {0},b[100100] = {0},c[100100] = {0},d[100100] = {0};
void wsort(int l,int r){
if(l >= r){
return ;
}
int k = rand() % (r - l + 1) + l,l1 = 0,l2 = 0,l3 = 0;
for(int i = l;i <= r;i++){
if(a[i] < a[k]){
b[l1] = a[i];
l1++;
}else{
if(a[i] == a[k]){
c[l2] = a[i];
l2++;
}else{
d[l3] = a[i];
l3++;
}
}
}
for(int i = 0;i < l1;i++){
a[l + i] = b[i];
}
for(int i = 0;i < l2;i++){
a[l + l1 + i] = c[i];
}
for(int i = 0;i < l3;i++){
a[l + l1 + l2 + i] = d[i];
}
wsort(l,l1 - 1 + l);
wsort(l + l1 + l2,r);
}
int main(){
srand(time(0));
scanf("%d",&n);
for(int i = 0;i < n;i++){
scanf("%d",&a[i]);
}
wsort(0,n - 1);
for(int i = 0;i < n;i++){
printf("%d ",a[i]);
}
return 0;
}
代码功能概述
该代码实现了一个随机化的快速排序算法(Quicksort),用于对输入的整数数组进行排序。核心思路是通过随机选择基准值(pivot)将数组划分为三部分:小于基准、等于基准和大于基准的元素,再递归处理前两部分和后两部分。
关键变量与数据结构
a[100100]:存储待排序的原始数组,容量为100100。
b[100100]、c[100100]、d[100100]:临时数组,分别存储小于、等于和大于基准值的元素。
n:输入数组的长度。
wsort(l, r):递归排序函数,处理数组区间 [l, r]。
核心算法逻辑
随机选择基准值
通过 k = rand() % (r - l + 1) + l 在区间 [l, r] 中随机选择一个下标 k,其对应的值 a[k] 作为基准值。
三路划分
遍历区间 [l, r],将元素分类到临时数组:
b[]存储小于a[k]的元素。c[]存储等于a[k]的元素。d[]存储大于a[k]的元素。
合并与递归
将分类后的三部分按顺序写回原数组 a[]:
- 先写入
b[](小于基准的部分)。 - 接着写入
c[](等于基准的部分)。 - 最后写入
d[](大于基准的部分)。
递归调用wsort处理小于基准([l, l + l1 - 1])和大于基准([l + l1 + l2, r])的子区间。
主函数流程
- 初始化随机种子:
srand(time(0))。 - 输入数组长度
n和数组元素a[0..n-1]。 - 调用
wsort(0, n-1)排序。 - 输出排序后的数组。
代码特点与注意事项
随机化优化
通过随机选择基准值,避免最坏情况的时间复杂度退化(如数组已有序时普通快排的 $O(n^2)$ 复杂度)。
三路划分优势
处理重复元素时效率更高,避免重复元素导致的递归深度增加。
时空复杂度
- 时间复杂度:平均 O(n log n),最坏 O(n^2)(极低概率)。
- 空间复杂度:O(n)(临时数组占用)。
点个赞吧!!!求求了!!!
2696

被折叠的 条评论
为什么被折叠?



