快速排序这个自己想了一会,真的想不出来,还是查了资料,使用 C89 标准函数库有一个非常简单的写法,(维基上的不能跑,自己稍稍改了一下)
#include <stdio.h> #include <stdlib.h> static int cmp(int *a, int *b) { return *a-*b; } int main() { int arr[10]={5, 3, 7, 4, 1, 9, 8, 6, 2}; qsort(arr, 10, sizeof(int), (int(*) (const void *,const void *))cmp); return 0; }
而我交到 hdu 的是
#include <stdio.h> #define MAX 1005 int get(int arr[]) { int n, i; scanf("%d", &n); for (i=0; i<n; i++) { scanf("%d", &arr[i]); } return n; } void print(int arr[], int n) { printf("%d", arr[0]); int i; for (i=1; i<n; i++) { printf(" %d", arr[i]); } printf("n"); } void quick_sort(int arr[], int left, int right) { int i = left, j = right; int pivot = arr[(i+j)/2]; // printf("pivot is %dn", pivot); while (i <= j) { while (arr[i] < pivot) { i++; } while (arr[j] > pivot) { j--; } if (i <= j) { // printf("swapping arr[%d]:%d and arr[%d]:%dn", // i, arr[i], j, arr[j]); int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; i++; j--; } } if (left < j) { quick_sort(arr, left, j); } if (i < right) { quick_sort(arr, i, right); } } int main() { int t; scanf("%d", &t); while (t--) { int arr[MAX] = {0}; int n = get(arr); quick_sort(arr, 0, n-1); print(arr, n); } return 0; }
最后,附上一个 python 的版本,再次体会到 python 的简洁
def qsort(L): if not L: return [] return qsort([x for x in L[1:] if x< L[0]]) + L[0:1] + qsort([x for x in L[1:] if x>=L[0]])
不仅简洁,而且思路非常清晰,易懂,不过 python 这个版本空间复杂度比较高就是了
==============================================================
2012-08-11 00:37:12 update: 上面那个快排,有两个地方想不懂:
- 在 31 行 while 循环那里,为什么需要小于等于呢,为什么不能去掉等号呢
- 在 52 和 56 行那里,为什么需要判断 if 呢,那个地方是一个递归终止条件这我知道,问题是,那个 if 在什么情况下会不成立呢,i 从左往右递增,怎么会超过 right 呢,同理 j 也一样啊
==============================================================
2012-08-11 01:01:26 update: 第二个问题看下面这个代码的输出应该就能有体会了,具体我也不知道怎么说
#include <stdio.h> #define MAX 1005 int total; int *p_arr; int get(int arr[]) { int n, i; scanf("%d", &n); for (i=0; i<n; i++) { scanf("%d", &arr[i]); } return n; } void print(int arr[], int n) { n = total; arr = p_arr; printf("%d", arr[0]); int i; for (i=1; i<n; i++) { printf(" %d", arr[i]); } printf("n"); } void quick_sort(int arr[], int left, int right) { int i = left, j = right; int pivot = arr[(i+j)/2]; printf("left is %d right is %d pivot is %dn", left, right, pivot); while (i <= j) { while (arr[i] < pivot) { i++; } while (arr[j] > pivot) { j--; } if (i <= j) { printf("swapping arr[%d]:%d and arr[%d]:%dn", i, arr[i], j, arr[j]); int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; i++; j--; print(arr, 0); } } if (left < j) { quick_sort(arr, left, j); } else { printf("left is %d and not smaller than j is %dn", left, j); } if (i < right) { quick_sort(arr, i, right); } else { printf("i is %d and not smaller than right is %dn", i, right); } } int main() { int t; scanf("%d", &t); while (t--) { int arr[MAX] = {0}; p_arr = arr; int n = get(arr); total = n; quick_sort(arr, 0, n-1); print(arr, n); printf("donen"); } return 0; }
至于第一个问题嘛,我把等于号删掉了,交到 hdu 上是可以过的,看起来应该是没问题的,但是怎么证明呢