Add Quick-Sort

This commit is contained in:
juan 2022-11-16 11:25:42 +08:00
parent 3e1009a9e9
commit 76a7e2000d
No known key found for this signature in database
GPG key ID: 5C1E5093C74F1DC7

View file

@ -1,56 +1,107 @@
#include <stdio.h>
#define N 10
#define CUTOFF 3
#define SIZE 10
void print(int *arr) {
for (int i = 0; i < N; i++) {
void swap(int *l, int *r) {
int tmp = *l;
*l = *r;
*r = tmp;
}
void print(int arr[]) {
for (int i = 0; i < SIZE; i++) {
printf("%d,", arr[i]);
}
printf("\n");
}
void swap(int *arr, int l, int r) {
if (l != r) {
int tmp = arr[l];
arr[l] = arr[r];
arr[r] = tmp;
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]);
}
// arr[l] <= arr[center] <= arr[r]
swap(&arr[center], &arr[r - 1]); // Hide pivot
return r - 1; // Return pivot
}
int partition(int *arr, int l, int r) {
// both edges included
int index = l;
int pivot = arr[l];
for (int i = l + 1; i <= r; i++) {
if (arr[i] < pivot) {
swap(arr, i, index);
index++;
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]);
}
}
}
swap(arr, index, l);
return index;
print(arr);
}
void quickSort(int *arr, int l, int r) {
void Qsort(int arr[], int l, int r, int pivotIndex) {
int i, j;
int pi;
if (l < r) {
if (r - l < CUTOFF) {
printf("insert(%d,%d):", l, r - l + 1);
if (l + CUTOFF <= r) {
if (pivotIndex == -1) {
pivotIndex = med3(arr, l, r);
i = l;
j = r - 1;
} else {
printf("Qsort(%d,%d):", l, r);
i = l - 1;
j = r;
}
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]
pi = partition(arr, l, r);
printf("Qsort(%d,%d):", l, r);
print(arr);
// 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);
quickSort(arr, l, pi - 1);
quickSort(arr, pi + 1, r);
} else {
insert(arr, l, r);
}
}
int main(void) {
int arr[] = {49, 38, 65, 97, 76, 13, 27, 50, 2, 8};
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);
return 0;
}