快速排序
快速排序是比较经典的排序方法,平均时间复杂度为O(nlogn),不深究如何推导此复杂度。
以下是本人造的轮子,做一个记录。
quicksort.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 5 #define B_SIZE 100 6 7 /*普通算法一般有3个参数,算法用到递归,减少一个参数对栈的压力减小*/ 8 void quicksort(int *p, int count) 9 { 10 int i = 0; 11 int j; 12 int ref; 13 if (count > 1) { 14 j = count - 1; 15 ref = *p; 16 while (i < j) { 17 while (i < j && ref <= *(p + j)) { 18 j--; 19 } 20 *(p + i) = *(p + j); 21 while (i < j && ref >= *(p + i)) { 22 i++; 23 } 24 *(p + j) = *(p + i); 25 } 26 *(p + i) = ref; 27 /*防止i = 0;无限调用quicksort(p, count)导致内存溢出*/ 28 i++; 29 quicksort(p, i); 30 quicksort(p + i, count - i); 31 } 32 } 33 34 void swap(int *x, int *y) 35 { 36 int t; 37 t = *x; 38 *x = *y; 39 *y = t; 40 } 41 42 int main(int argc, char const **argv) 43 { 44 int i; 45 int n; 46 int buff[B_SIZE]; 47 srand(time(0)); 48 for (i = 0; i < B_SIZE; i++) { 49 *(buff + i) = i; 50 } 51 52 for (n = B_SIZE; n > 0; n--) { 53 /*随机生成索引,并且和末尾索引的数据交换位置,形成真正的随机且不重复的数据*/ 54 swap(buff + rand() % n, buff + n - 1); 55 } 56 57 printf("-------------the raw data-------------\n"); 58 for (i = 0; i < B_SIZE; i++) { 59 printf("%5d", *(buff + i)); 60 if ((i + 1) % 10 == 0) 61 printf("\n"); 62 } 63 quicksort(buff, B_SIZE); 64 printf("-------------the processed data-------------\n"); 65 for (i = 0; i < B_SIZE; i++) { 66 printf("%5d", *(buff + i)); 67 if ((i + 1) % 10 == 0) 68 printf("\n"); 69 } 70 return 0; 71 }
快速排序算法思路是:
1:选一个参考ref(上例选的是p[0]),并缓存起来;
2:在右侧(索引号大的一侧,初始为末端)逐一(j--)选取比ref小的值放在左侧(索引号小的一侧,初始为0),且左侧的索引号递增(i++).
3:在左侧逐一(i++)选取比ref大的值放在右侧,且右侧的索引号递减(j--);
4:当左侧索引等于右侧索引时,把ref的赋值到此时的索引号对应的值,此时左侧的值均比ref小,右侧的值均比ref大;
5:以ref为临界点分别为左侧和右侧循环步骤1-4;