几种快速排序的实现(C语言描述)

  快速排序是对冒泡排序的改进,主要思想是通过一次排序将序列分成两部分,左边的部分全部小于基准值,右边的部分大于基准值。在这一思想下,有不同的几种实现方式。

(以下代码中的测试数据来自用系统时间做种的随机生成序列)

(除了以下版本,还有一些其他的快排的想法。)

1. 比较好理解的版本

 1 /*
2 *2012年2月13日11:28:00
3 *quickSort
4 *这个版本是比较好理解的版本(效率不是最高的)
5 *quickSort函数第二个参数是要排序的数组起始下标,第三个参数是结束下标
6 *过程:
7 *1. 将最左边的数设为val(也即关键字)
8 *2. 从i开始向右找比val大的数,找到后停下
9 *3. 从j开始向左找比val小的数,找到后停下
10 *4. 如果i>=j则离开循环
11 *5. 否则:交换当前的两个数
12 *6. 对左边递归
13 *7. 对右边递归
14 */
15
16 #include <stdio.h>
17 #include <time.h>
18
19 #define MAX 10
20 #define SWAP(x, y) {int t=x; x=y; y=t;}
21
22 void quickSort(int *a, int left, int right);
23
24 int main(void)
25 {
26 int a[MAX] = {0};
27 int i;
28
29 srand(time(NULL));
30
31 printf("排序前:\n");
32 for (i=0; i<MAX; i++)
33 {
34 a[i] = rand()%100;
35 printf("%d ", a[i]);
36 }
37
38 quickSort(a, 0, MAX-1);
39
40 printf("\n排序后:\n");
41 for (i=0; i<MAX; i++)
42 {
43 printf("%d ", a[i]);
44 }
45 printf("\n");
46
47 return 0;
48 }
49
50 void quickSort(int *a, int left, int right)
51 {
52 if (left < right)
53 {
54 int i = left;
55 int j = right+1;
56
57 while (1)
58 {
59 while (i+1<MAX && a[++i]<a[left]);
60 while (j-1>-1 && a[--j]>a[left]);
61
62 if (i >= j)
63 {
64 break;
65 }
66 SWAP(a[i], a[j]);
67 }
68
69 SWAP(a[left], a[j]);
70
71 quickSort(a, left, j-1);
72 quickSort(a, j+1, right);
73 }
74 }

2. 对于上述方法进行改进,将基准值设定为序列中间的数,从中间向两边寻找

 1 /*
2 *2012年2月13日16:26:31
3 *从中间向两边查找,具体过程类似于容易理解的版本
4 */
5
6 #include <stdio.h>
7 #include <time.h>
8
9 #define MAX 10
10 #define SWAP(x, y) {int t=x; x=y; y=t;}
11
12 void quickSort(int *a, int left, int right);
13
14 int main(void)
15 {
16 int a[MAX] = {0};
17 int i;
18
19 srand(time(NULL));
20
21 printf("排序前:\n");
22 for (i=0; i<MAX; i++)
23 {
24 a[i] = rand()%100;
25 printf("%d ", a[i]);
26 }
27
28 quickSort(a, 0, MAX-1);
29
30 printf("\n排序后:\n");
31 for (i=0; i<MAX; i++)
32 {
33 printf("%d ", a[i]);
34 }
35 printf("\n");
36
37 return 0;
38 }
39
40 void quickSort(int *a, int left, int right)
41 {
42 if (left < right)
43 {
44 int t = a[(left+right)/2];
45 int i = left - 1;
46 int j = right + 1;
47
48 while (1)
49 {
50 while (a[++i] < t);
51 while (a[--j] > t);
52
53 if (i >= j)
54 {
55 break;
56 }
57 SWAP(a[i], a[j]);
58
59 }
60
61 quickSort(a, left, i-1);
62 quickSort(a, j+1, right);
63 }
64 }

3. 再次改进算法。

      有指针left和right,对于right,如果其所指的元素的值大于或者等于基准值,那么指针往左移一位,如果小于基准值,则和基准值交换;同理,对于left,如果left所指元素的值小于或者等于基准值,那么指针往右移一位,如果大于基准值,则和基准值交换。从right开始执行,重复这两步骤,直至left == right为止。

  对于基准的选取会影响算法的性能,这里取第一个元素为pivot。

 1 /*
2 *2012年2月13日16:42:45
3 *效率较高的实现
4 */
5
6 #include <stdio.h>
7 #include <time.h>
8
9 #define MAX 10
10 #define SWAP(x, y) {int t=x; x=y; y=t;}
11
12 void quickSort(int *a, int left, int right);
13 int Partition(int *a, int left, int right);
14
15 int main(void)
16 {
17 int a[MAX] = {0};
18 int i;
19
20 srand(time(NULL));
21
22 printf("排序前:\n");
23 for (i=0; i<MAX; i++)
24 {
25 a[i] = rand()%100;
26 printf("%d ", a[i]);
27 }
28
29 quickSort(a, 0, MAX-1);
30
31 printf("\n排序后:\n");
32 for (i=0; i<MAX; i++)
33 {
34 printf("%d ", a[i]);
35 }
36 printf("\n");
37
38 return 0;
39 }
40
41 int Partition(int *a, int left, int right)
42 {
43 int pivot = a[left];
44 while (left < right)
45 {
46 while (left < right && a[right] >= pivot)
47 {
48 --right;
49 }
50 a[left] = a[right];
51 while (left < right && a[left] <= pivot)
52 {
53 ++left;
54 }
55 a[right] = a[left];
56 }
57
58 return left;
59 }
60
61 void quickSort(int *a, int left, int right)
62 {
63 int pivot;
64
65 if (left < right)
66 {
67 pivot = Partition(a, left, right);
68 quickSort(a, left, pivot-1);
69 quickSort(a, pivot+1, right);
70 }
71
72 }





  

posted @ 2012-02-13 16:54  漂木  阅读(8048)  评论(1编辑  收藏  举报