给定包含n个元素的整型数组a[1],a[2],...,a[n],利用快速排序算法对其进行递增排序,请输出排序过程,即每次Partition之后的数组。最后输出排序后的数组。每次选择所处理的子数组的第一个元素作为基准元素。
输入格式:
输入为两行,第一行为一个整数n(1<n≤1000),表示数组长度。第二行为n个空格间隔的整数,表示待排序的数组。
输出格式:
输出为若干行,每行依次输出Partition后的数组,每个元素后一个空格。最后一行输出排序后的数组。
输入样例:
5
4 5 3 2 1
输出样例:
2 1 3 4 5
1 2 3 4 5
1 2 3 4 5
代码长度限制
16 KB
时间限制
150 ms
内存限制
64 MB
思路
- 定义一个函数
partition
,用于将数组分割为两部分,并确定基准元素的最终位置。函数中使用两个指针i
和j
,分别指向数组的起始位置和末尾位置。 - 从数组的起始位置开始,逐个比较元素与基准元素的大小。
- 如果元素小于等于基准元素,将
i
指针向后移动一位。 - 如果元素大于基准元素,将
j
指针向前移动一位。 - 如果
i
指针仍然小于j
指针,交换i
和j
指针所指向的元素。
- 如果元素小于等于基准元素,将
- 重复步骤 2,直到
i
指针大于等于j
指针。 - 将基准元素与
j
指针所指向的元素进行交换,将基准元素放到最终的位置。 - 通过递归调用
partition
函数,对基准元素左边的子数组和右边的子数组进行排序。 - 递归终止条件是子数组的长度为 0 或 1,不需要进行排序。
在代码中,quicksort
函数实现了上述快速排序的思路。通过递归调用 quicksort
函数对子数组进行排序,并使用 partition
函数将数组分割为两部分。每次递归调用都会确定一个元素的最终位置,直到整个数组有序。
代码
#include <stdio.h>
int n;
// 输出数组
void print(int arr[]) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
// 交换两个元素的值
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
// 快速排序
void quicksort(int arr[], int left, int right) {
if (left >= right) {
return;
}
int l = left;
int r = right;
int key = arr[left]; // 选择第一个元素作为基准值
while (l < r) {
// 从右往左找第一个小于等于基准值的元素
while (l < r && arr[r] > key) {
r--;
}
// 从左往右找第一个大于基准值的元素
while (l < r && arr[l] <= key) {
l++;
}
// 交换找到的两个元素
swap(&arr[r], &arr[l]);
}
// 将基准值放到最终位置
swap(&arr[l], &arr[left]);
print(arr); // 打印每次Partition后的数组
// 递归调用快速排序对分割后的子数组进行排序
quicksort(arr, left, l - 1);
quicksort(arr, l + 1, right);
}
int main() {
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
quicksort(arr, 0, n - 1); // 调用快速排序算法
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}