#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define BUFSIZE 19 void swap(int *arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } int Random(int left, int right) { time_t t; srand((unsigned int)time(&t)); return left + rand() % (right-left+1); } int Partition(int *arr, int left, int right) { int pivot = arr[right]; int j = left; for (int i = left; i < right; i++) { if (arr[i] <= pivot) swap(arr, j++, i); } swap(arr, j, right); return j; } int PartitionA(int *arr, int left, int right) { int pivot = arr[right]; int j = left - 1; for (int i = left; i < right; i++) { if (arr[i] <= pivot) swap(arr, ++j, i); } swap(arr, j + 1, right); return j + 1; } int PartitionB(int *arr, int left, int right) { // 选中间元素作为枢纽 swap(arr, left, (left + right) / 2); int pivot = arr[left]; int j = left; for (int i = left + 1; i <= right; i++) { if (arr[i] <= pivot) swap(arr, ++j, i); } swap(arr, j, left); return j; } int PartitionC(int *arr, int left, int right) { int last = Random(left, right); // 随机化快排 swap(arr, right, last); int pivot = arr[right]; int j = left - 1; for (int i = left; i < right; i++) { if (arr[i] <= pivot) swap(arr, ++j, i); } swap(arr, j + 1, right); return j + 1; } int Partition1(int *arr, int left, int right) { int pivot = arr[left]; while (left < right) { // [) ro (] // 从右边开始 while (left < right && arr[right] >= pivot) right--; arr[left] = arr[right]; while (left < right && arr[left] <= pivot) left++; arr[right] = arr[left]; } arr[left] = pivot; return right; } int Partition2(int *arr, int left, int right) { int pivot = arr[right]; while (left < right) { // 从左边开始 while (left < right && arr[left] <= pivot) left++; arr[right] = arr[left]; while (left < right && arr[right] >= pivot) right--; arr[left] = arr[right]; } arr[right] = pivot; return left; } int Partition3(int *arr, int left, int right) { int pivot = arr[right]; int end = right; while (left < right) { while (left < right && arr[left] <= pivot) left++; while (left < right && arr[right] >= pivot) right--; if (left < right) swap(arr, left, right); } if (right != end) swap(arr, right, end); return left; // 谁先操作返回谁 } int Partition4(int *arr, int left, int right) { int pivot = arr[left]; int i = left - 1; int j = right + 1; while (1) { while (arr[--j] > pivot) ; while (arr[++i] <= pivot) ; if (i < j) swap(arr, i, j); else break; } swap(arr, left, j); return j; } // 如何证明它有bug? ^-^ int Partition5(int *arr, int left, int right) { int pivot = arr[left]; int i = left - 1; int j = right + 1; while (i < j) { while (i < j && arr[--j] > pivot) ; while (i < j && arr[++i] < pivot) ; // do { // j--; // } while (arr[j] > pivot); // do { // i++; // } while (arr[i] < pivot); if (i < j) swap(arr, i, j); else return j; } } void QuickSort(int *arr, int left, int right) { if (left >= right) return ; int pivot = PartitionC(arr, left, right); QuickSort(arr, left, pivot - 1); QuickSort(arr, pivot + 1, right); } void StoogeSort(int *arr, int left, int right) { if (arr[left] > arr[right]) swap(arr, left, right); if (left + 1 >= right) return ; int k = (right - left + 1) / 3; StoogeSort(arr, left, right - k); StoogeSort(arr, left + k, right); StoogeSort(arr, left, right - k); } #define MAX_BUF 256 int numcmp(char *pa, char *pb) { return (*(int *)pa - *(int *)pb); } void *mybsearch(const void *key, const void *base, size_t n, size_t size, int (*cmp)(const void *, const void *)) { const char *p; size_t m; for (p = (const char *)base, m = n; m > 0; ) { const size_t pivot = n >> 1; const char *const q = p + size * pivot; const int val = (*cmp)(key, q); if (val < 0) { /* search below pivot */ n = pivot; } else if (val == 0) { return ((void *)q); } else { /* search above pivot */ p = q + size; n -= pivot + 1; } } return NULL; } // 如part3框架一样 void myqsort(void *base, size_t n, size_t size, int (*cmp)(const void *, const void *)) { while (1 < n) { size_t i = 0; size_t j = n - 1; char *qi = (char *)base; char *qj = qi + size * j; // 指向最后一个元素 char *qp = qj; // 选择最后一个点作为pivot while (i < j) { while (i < j && (*numcmp)(qi, qp) <= 0) ++i, qi += size; while (i < j && (*numcmp)(qp, qj) <= 0) --j, qj -= size; if (i < j) { /* swap elements i and j */ char buf[MAX_BUF]; char *q1 = qi; char *q2 = qj; size_t m, ma; for (ma = size; 0 < ma; ma -= m, q1 += m, q2 -= m) { m = ma < sizeof(buf) ? ma : sizeof(buf); memcpy(buf, q1, m); memcpy(q1, q2, m); memcpy(q2, buf, m); } ++i, qi += size; } } /* swap elements i and pivot */ if (qi != qp) { char buf[MAX_BUF]; char *q1 = qi; char *q2 = qp; size_t m, ma; for (ma = size; 0 < ma; ma -= m, q1 += m, q2 -= m) { m = ma < sizeof(buf) ? ma : sizeof(buf); memcpy(buf, q1, m); memcpy(q1, q2, m); memcpy(q2, buf, m); } } j = n - i - 1; qi += size; if (j < i) { /* recurse on smaller partition */ if (1 < j) qsort(qi, j, size, cmp); n = i; } else { /* lower partition is smaller */ if (1 < i) qsort(base, i, size, cmp); base = qi; n = j; } } } int main() { int arr[] = {17, 5, 9, 21, 6, 123, 24, 8, 34, 324, 3, 23, 54, 22, 57, 234, 7, 12, 234}; /*int arr[8] = {234, 123, 76, 76, 54, 43, 32, 21};*/ /*int arr[8] = {1, 45, 43, 45, 65, 45, 87, 353};*/ int len = sizeof(arr) / sizeof(arr[0]); printf("array:"); for (int i = 0; i < len; i++) { printf("%-8d", arr[i]); } printf("\n"); QuickSort(arr, 0, len - 1); //StoogeSort(arr, 0, BUFSIZE - 1); //myqsort(arr, BUFSIZE, sizeof(int), (int (*)(const void *, const void *))numcmp); printf("quick:"); for (int i = 0; i < len; i++) { printf("%d\t", arr[i]); } printf("\n"); getchar(); return 0; }