(1)选择中值,根据坐标,三者取其中
(2)分别与中值比较,将数据分成两部分
(3)两部分中分别再使用同样的方法,分成更小的两部分,直到不可再分
(4)qksort中的递归,可以保证a[0]~a[j]完全排序,所以i = j+1;
代码:
root@ubuntu:/mnt/shared/appbox/qksort# cat qksort.c #include <stdlib.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <stdio.h> static int compare_int(const void *int1, const void *int2) { if(*(const int *)int1 == *(const int *)int2) return 0; return *(const int *)int1 > *(const int *)int2 ? 1 : -1; } static int get_mid_value(int *data) { if(compare_int(&data[0], &data[1])>0)//d[0]>d[1] { if(compare_int(&data[0], &data[2]) > 0) return compare_int(&data[1], &data[2]) > 0 ? data[1] : data[2]; else return data[0]; } else // d[0] < d[1] { if(compare_int(&data[0], &data[2]) > 0)//d[0] > d[2] return data[0]; // d[2]<d[0]<d[1], return d[0] else//d[0] < d[2] return compare_int(&data[1] ,&data[2]) > 0? data[2]:data[1]; } return -1; } static int partition(int *a, int esize, int i, int k, int (*compare)(const void *key1, const void *key2)) { int m; int mid, middle; int r[3]; int temp; r[0] = (rand()%(k-i+1) + i); r[1] = (rand()%(k-i+1) + i); r[2] = (rand()%(k-i+1) + i); mid = get_mid_value(r); middle = a[mid]; printf("r[0]:%d, r[1]:%d, r[2]:%d, mid:%d,middle:%d\n", r[0],r[1],r[2],mid, middle); i--; k++; while(1) { do { k--; }while(compare(&a[k], &middle) > 0); do { i++; }while(compare(&a[i], &middle) < 0); if(i>=k) break; else { temp = a[i]; a[i] = a[k]; a[k] = temp; } } return k; } int qksort(void *data, int size, int esize, int i, int k, int (*compare)(const void *key1, const void *key2)) { int j; int m; while(i < k) { if((j = partition(data, esize, i, k, compare)) < 0) return -1; if(qksort(data, size, esize, i, j, compare) < 0) return -1; i = j + 1; } return 0; } int main(int argc, char *argv[]) { int ret; int i, j, k; i = 11; j = 12; int array[10]= {1,4,7,2,5,8,3,6,9,10}; printf("\n******************compare_init test**********************\n"); printf("compare_int(&i, &j)=%d\n", compare_int(&i, &j)); printf("compare_int(&j, &i)=%d\n", compare_int(&j, &i)); printf("compare_int(&i, &i)=%d\n", compare_int(&i, &i)); printf("\n******************partition test**********************\n"); qksort(array, 10, 4, 0, 9, compare_int); for(i=0; i<10; i++) printf("%d ", array[i]); printf("\n"); return 0; }
root@ubuntu:/mnt/shared/appbox/qksort# ./qksort
******************compare_init test**********************
compare_int(&i, &j)=-1
compare_int(&j, &i)=1
compare_int(&i, &i)=0
******************partition test**********************
r[0]:3, r[1]:6, r[2]:7, mid:6,middle:3
r[0]:1, r[1]:2, r[2]:1, mid:1,middle:3
r[0]:0, r[1]:0, r[2]:1, mid:0,middle:1
r[0]:6, r[1]:5, r[2]:8, mid:6,middle:4
r[0]:6, r[1]:5, r[2]:9, mid:6,middle:7
r[0]:5, r[1]:4, r[2]:4, mid:4,middle:5
r[0]:5, r[1]:5, r[2]:6, mid:5,middle:6
r[0]:9, r[1]:7, r[2]:7, mid:7,middle:8
r[0]:8, r[1]:8, r[2]:8, mid:8,middle:9
1 2 3 4 5 6 7 8 9 10
root@ubuntu:/mnt/shared/appbox/qksort#
增加对流程的打印:
root@ubuntu:/mnt/shared/appbox/qksort# cat qksort.c #include <stdlib.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <stdio.h> static int compare_int(const void *int1, const void *int2) { if(*(const int *)int1 == *(const int *)int2) return 0; return *(const int *)int1 > *(const int *)int2 ? 1 : -1; } static int get_mid_value(int *data) { if(compare_int(&data[0], &data[1])>0)//d[0]>d[1] { if(compare_int(&data[0], &data[2]) > 0) return compare_int(&data[1], &data[2]) > 0 ? data[1] : data[2]; else return data[0]; } else // d[0] < d[1] { if(compare_int(&data[0], &data[2]) > 0)//d[0] > d[2] return data[0]; // d[2]<d[0]<d[1], return d[0] else//d[0] < d[2] return compare_int(&data[1] ,&data[2]) > 0? data[2]:data[1]; } return -1; } static int partition(int *a, int esize, int i, int k, int (*compare)(const void *key1, const void *key2)) { int m; int mid, middle; int r[3]; int temp; r[0] = (rand()%(k-i+1) + i); r[1] = (rand()%(k-i+1) + i); r[2] = (rand()%(k-i+1) + i); mid = get_mid_value(r); middle = a[mid]; printf("r[0]:%d, r[1]:%d, r[2]:%d, mid:%d,middle:%d\n", r[0],r[1],r[2],mid, middle); i--; k++; while(1) { do { k--; }while(compare(&a[k], &middle) > 0); do { i++; }while(compare(&a[i], &middle) < 0); if(i>=k) break; else { temp = a[i]; a[i] = a[k]; a[k] = temp; } } return k; } int qksort(void *data, int size, int esize, int i, int k, int (*compare)(const void *key1, const void *key2)) { int j; int m; while(i < k) { printf("\n--------------------------------------------------\n"); printf("i=%d, k=%d\n", i, k); for(m=0; m<10; m++) printf("%d ", ((int *)data)[m]); printf("\n"); if((j = partition(data, esize, i, k, compare)) < 0) return -1; printf("j=%d, a[j]:%d\n", j, ((int *)data)[j]); for(m=0; m<10; m++) printf("%d ", ((int *)data)[m]); printf("\n"); if(qksort(data, size, esize, i, j, compare) < 0) return -1; for(m=0; m<10; m++) printf("%d ", ((int *)data)[m]); printf("\n"); i = j + 1; } return 0; } int main(int argc, char *argv[]) { int ret; int i, j, k; i = 11; j = 12; int array[10]= {1,4,7,2,5,8,3,6,9,10}; printf("\n******************compare_init test**********************\n"); printf("compare_int(&i, &j)=%d\n", compare_int(&i, &j)); printf("compare_int(&j, &i)=%d\n", compare_int(&j, &i)); printf("compare_int(&i, &i)=%d\n", compare_int(&i, &i)); printf("\n******************partition test**********************\n"); qksort(array, 10, 4, 0, 9, compare_int); for(i=0; i<10; i++) printf("%d ", array[i]); printf("\n"); return 0; } root@ubuntu:/mnt/shared/appbox/qksort#
root@ubuntu:/mnt/shared/appbox/qksort# ./qksort ******************compare_init test********************** compare_int(&i, &j)=-1 compare_int(&j, &i)=1 compare_int(&i, &i)=0 ******************partition test********************** -------------------------------------------------- i=0, k=9 1 4 7 2 5 8 3 6 9 10 r[0]:3, r[1]:6, r[2]:7, mid:6,middle:3 j=2, a[j]:2 1 3 2 7 5 8 4 6 9 10 -------------------------------------------------- i=0, k=2 1 3 2 7 5 8 4 6 9 10 r[0]:1, r[1]:2, r[2]:1, mid:1,middle:3 j=1, a[j]:2 1 2 3 7 5 8 4 6 9 10 -------------------------------------------------- i=0, k=1 1 2 3 7 5 8 4 6 9 10 r[0]:0, r[1]:0, r[2]:1, mid:0,middle:1 j=0, a[j]:1 1 2 3 7 5 8 4 6 9 10 1 2 3 7 5 8 4 6 9 10 1 2 3 7 5 8 4 6 9 10 1 2 3 7 5 8 4 6 9 10 -------------------------------------------------- i=3, k=9 1 2 3 7 5 8 4 6 9 10 r[0]:6, r[1]:5, r[2]:8, mid:6,middle:4 j=3, a[j]:4 1 2 3 4 5 8 7 6 9 10 1 2 3 4 5 8 7 6 9 10 -------------------------------------------------- i=4, k=9 1 2 3 4 5 8 7 6 9 10 r[0]:6, r[1]:5, r[2]:9, mid:6,middle:7 j=6, a[j]:7 1 2 3 4 5 6 7 8 9 10 -------------------------------------------------- i=4, k=6 1 2 3 4 5 6 7 8 9 10 r[0]:5, r[1]:4, r[2]:4, mid:4,middle:5 j=4, a[j]:5 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 -------------------------------------------------- i=5, k=6 1 2 3 4 5 6 7 8 9 10 r[0]:5, r[1]:5, r[2]:6, mid:5,middle:6 j=5, a[j]:6 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 -------------------------------------------------- i=7, k=9 1 2 3 4 5 6 7 8 9 10 r[0]:9, r[1]:7, r[2]:7, mid:7,middle:8 j=7, a[j]:8 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 -------------------------------------------------- i=8, k=9 1 2 3 4 5 6 7 8 9 10 r[0]:8, r[1]:8, r[2]:8, mid:8,middle:9 j=8, a[j]:9 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10