快速排序

快速排序算法的基本思想是,对于输入的子数组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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值