快速排序算法的基本思想是,对于输入的子数组arr[b:e],按一下三个步骤进行排序:
(1) 分解:以arr[b]为基准将arr[b:e]划分为三段arr[b:t-1],arr[t],arr[t+1:e],使arr[b:t-1]中的任何一个元素小于等于arr[t],而arr[t+1:e]中的任何一个元素大于等于arr[t]。下标t在划分过程中确定。
(2) 递归求解:通过递归调用快速排序算法分别对arr[b:t-1]和arr[t+1:e]进行排序。
(3) 合并:由于对arr[b:t-1]和arr[t+1:e]的排序是就地进行的,所以在arr[b:t-1]和arr[t+1:e]排序后,不需求再进行任何计算。
代码实现:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef int TYPE;
#define PRINT_FORMAT "%-3d "
#define ARR_LEN 100
int main(void) {
void get_random_arr(TYPE arr[], int len);
void print_arr(TYPE arr[], int len);
void quick_sort(TYPE arr[], int len);
TYPE arr[ARR_LEN];
get_random_arr(arr, ARR_LEN);
printf("Befor Sorting:\n");
print_arr(arr, ARR_LEN);
quick_sort(arr, ARR_LEN);
printf("After Sorting:\n");
print_arr(arr, ARR_LEN);
return EXIT_SUCCESS;
}
/*
** 快速排序
*/
void quick_sort(TYPE arr[], int len) {
void q_sort(TYPE arr[], int begin, int end);
q_sort(arr, 0, len-1);
}
/*
** 对数组arr[begin:end]进去快速排序
*/
void q_sort(TYPE arr[], int begin, int end) {
int partition(TYPE arr[], int begin, int end);
int base_pos;
if (begin < end) {
base_pos = partition(arr, begin, end);
/*
** 对左区域排序
*/
q_sort(arr, begin, base_pos-1);
/*
** 对右区域排序
*/
q_sort(arr, base_pos+1, end);
}
}
/*
** 将对arr[begin:end]以arr[begin]作为基准进行划分,
** 大于基准的元素置于左区域,
** 小于基准的元素置于右区域。
** 将基准元素置于确定好的位置,并返回其位置
*/
int partition(TYPE arr[], int begin, int end) {
void swap(TYPE *a, TYPE *b);
TYPE base = arr[begin]; // 以arr[begin]作为基准
int i = begin;
int j = end + 1;
while (1) {
/*
** 将小于base的元素放在左区域,
** 将大于base的元素放在右区域。
*/
while (arr[++i] < base && i < end)
;
while (arr[--j] > base)
;
if (i >= j) break;
swap(&arr[i], &arr[j]);
}
arr[begin] = arr[j];
arr[j] = base;
return j;
}
void swap(TYPE *a, TYPE *b) {
TYPE tmp = *a;
*a = *b;
*b = tmp;
}
/*
** 简单地获取随机数组
*/
void get_random_arr(TYPE arr[], int len) {
int i;
srand((unsigned int)time(NULL));
for (i = 0; i < len; i++) {
arr[i] = rand() % 100;
}
}
/*
** 打印数组
*/
void print_arr(TYPE arr[], int len) {
int i;
for (i = 0; i < len; i++) {
printf(PRINT_FORMAT, arr[i]);
if ((i + 1) % 10 == 0)
putchar('\n');
}
putchar('\n');
}
结果输出:
Befor Sorting:
58 71 50 78 10 96 32 35 43 56
52 81 72 85 57 68 65 88 41 55
52 30 88 50 12 32 36 57 67 46
11 28 98 66 2 37 50 55 63 73
61 92 9 19 29 55 94 62 56 98
18 97 33 76 83 12 39 95 24 40
91 4 41 22 46 71 43 33 31 90
36 41 82 60 10 92 74 39 84 51
52 73 17 88 56 41 23 3 36 34
83 50 79 88 76 97 83 7 41 53
After Sorting:
2 3 4 7 9 10 10 11 12 12
17 18 19 22 23 24 28 29 30 31
32 32 33 33 34 35 36 36 36 37
39 39 40 41 41 41 41 41 43 43
46 46 50 50 50 50 51 52 52 52
53 55 55 55 56 56 56 57 57 58
60 61 62 63 65 66 67 68 71 71
72 73 73 74 76 76 78 79 81 82
83 83 83 84 85 88 88 88 88 90
91 92 92 94 95 96 97 97 98 98