Add Quick-Sort
This commit is contained in:
parent
3e1009a9e9
commit
76a7e2000d
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue