BUPT-homework/semester3/pset5/7-3-Quick-Sort.c

108 lines
2.3 KiB
C
Raw Permalink Normal View History

2022-11-13 21:16:43 +08:00
#include <stdio.h>
#define CUTOFF 3
2022-11-16 11:25:42 +08:00
#define SIZE 10
2022-11-13 21:16:43 +08:00
2022-11-16 11:25:42 +08:00
void swap(int *l, int *r) {
int tmp = *l;
*l = *r;
*r = tmp;
}
void print(int arr[]) {
for (int i = 0; i < SIZE; i++) {
2022-11-13 21:16:43 +08:00
printf("%d,", arr[i]);
}
2022-11-16 11:25:42 +08:00
printf("\n");
2022-11-13 21:16:43 +08:00
}
2022-11-16 11:25:42 +08:00
int med3(int arr[], int l, int r) {
// remember, it's (l + r)
int center = (l + r) / 2;
// printf("l:%d\t r:%d\t center:%d\n", l, r, center);
if (arr[l] > arr[center]) {
swap(&arr[l], &arr[center]);
}
if (arr[l] > arr[r]) {
swap(&arr[l], &arr[r]);
}
if (arr[center] > arr[r]) {
swap(&arr[center], &arr[r]);
2022-11-13 21:16:43 +08:00
}
2022-11-16 11:25:42 +08:00
// arr[l] <= arr[center] <= arr[r]
swap(&arr[center], &arr[r - 1]); // Hide pivot
return r - 1; // Return pivot
2022-11-13 21:16:43 +08:00
}
2022-11-16 11:25:42 +08:00
void insert(int arr[], int l, int r) {
// actually bubble sort is easier to implement
printf("insert(%d,%d):", l, r - l + 1);
// rememver using <=, because r is visited
for (int i = l; i <= r; i++) {
for (int j = l; j <= r - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(&arr[j], &arr[j + 1]);
}
2022-11-13 21:16:43 +08:00
}
}
2022-11-16 11:25:42 +08:00
print(arr);
2022-11-13 21:16:43 +08:00
}
2022-11-16 11:25:42 +08:00
void Qsort(int arr[], int l, int r, int pivotIndex) {
int i, j;
2022-11-13 21:16:43 +08:00
2022-11-16 11:25:42 +08:00
if (l + CUTOFF <= r) {
if (pivotIndex == -1) {
pivotIndex = med3(arr, l, r);
i = l;
j = r - 1;
2022-11-13 21:16:43 +08:00
} else {
2022-11-16 11:25:42 +08:00
i = l - 1;
j = r;
2022-11-13 21:16:43 +08:00
}
2022-11-16 11:25:42 +08:00
while (1) {
while (arr[++i] < arr[pivotIndex]) {
}
while (arr[--j] > arr[pivotIndex]) {
}
if (i < j && i != pivotIndex && j != pivotIndex) {
swap(&arr[i], &arr[j]);
} else {
break;
}
}
// printf("i:%d\n", i);
swap(&arr[i], &arr[pivotIndex]); // swap back arr[pivotIndex]
2022-11-13 21:16:43 +08:00
2022-11-16 11:25:42 +08:00
printf("Qsort(%d,%d):", l, r);
2022-11-13 21:16:43 +08:00
print(arr);
2022-11-16 11:25:42 +08:00
// from here on, use med3-generated arr[pivotIndex]
if (i != r) {
Qsort(arr, l, i - 1, -1);
} else {
Qsort(arr, l, i, -1);
}
Qsort(arr, i + 1, r, -1);
2022-11-13 21:16:43 +08:00
2022-11-16 11:25:42 +08:00
} else {
insert(arr, l, r);
2022-11-13 21:16:43 +08:00
}
}
int main(void) {
int arr[] = {49, 38, 65, 97, 76, 13, 27, 50, 2, 8};
2022-11-16 11:25:42 +08:00
int pivotIndex; // pivot == 8, pivot == 4, other 2 cases pivot <= 3
scanf("%d", &pivotIndex);
swap(&arr[pivotIndex], &arr[SIZE - 1]);
// make sure arr[0] is smaller, arr[r] is larger.
// remember the pivot index is changed to SIZE - 1
Qsort(arr, 0, SIZE - 1, SIZE - 1);
// Qsort(arr, 0, SIZE - 1, pivotIndex);
2022-11-13 21:16:43 +08:00
return 0;
}