From 76a7e2000d526b2a982a922f08a3a5dcb6bc0c3c Mon Sep 17 00:00:00 2001 From: juan Date: Wed, 16 Nov 2022 11:25:42 +0800 Subject: [PATCH] Add Quick-Sort --- semester3/pset5/7-3-Quick-Sort.c | 109 +++++++++++++++++++++++-------- 1 file changed, 80 insertions(+), 29 deletions(-) diff --git a/semester3/pset5/7-3-Quick-Sort.c b/semester3/pset5/7-3-Quick-Sort.c index 618b1b4..3ddd678 100644 --- a/semester3/pset5/7-3-Quick-Sort.c +++ b/semester3/pset5/7-3-Quick-Sort.c @@ -1,56 +1,107 @@ #include -#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; }