快排的两种写法

本文详细介绍了快速排序算法的原理及其实现方式,通过两种不同的优化方案展示了如何减少排序过程中的空间消耗,并提供了具体的C语言实现代码。

快速排序,原理很简单就是在数据找一个定点数,把小于这个数的数放到其左边,大于这个定点数的数放到其右边,再把左边的数,右边的数再按这种方式来排序,直至无数可排.

先实现,不求空间消耗, 把小于定点的数放一个数组 b, 把大于定点的数的放一个数组 c, 再把它们拷回数组 a

int quick_sort(int *a, int begin ,int end)
{

	if(begin >= end){
		return 0;
	}
        int size = end - begin + 1;
        int *b = malloc(size*sizeof(int));
        int *c = malloc(size*sizeof(int));
	int i;
	int j;
        int k;
  	int value = a[end];
        j = 0;
        k = 0;
	for(i = begin ; i < = end;i++ ){
		if(a[i] < value && i < j){
			b[j++] = a[i];
		}else{
                        c[k++] = a[i];
                }
	}
        for(i = 0; i < j ; i++){
            a[i] = b[i];
        }
        a[i] = value;
         for(i = 0; i < k ; i++){
            a[i+j] = c[i];
        }
        free(b);
        free(c);
    
	quick_sort(a, begin, j - 1);
	quick_sort(a, j+1, end);
	return 0;
}

void show(int *a, int size)
{
        int i;
	for(i = 0; i <= size; i++){
		printf("%d ", a[i]);
	}
	printf("\n");
}

int main(){

	int a[] = {1, 2, 3, 4, 1, 3, 4, 5, 10, 11, 13, 234, 3,5,7,4,2,1,8,9,6};
	int size= sizeof(a)/sizeof(int)- 1;
	quick_sort(a, 0, size);
        show(a, size);
        quick_sort2(a, 0, size);
	show(a, size);
	return 0;
}

下面再做空间优化, 数组 a, 起始位置 begin, 结束位置 end

第一种:

  1. 设置比较点 value = a[end],i  = begin
  2. 从左开始找到 >= value 的数的位置 i , 并设 j = i + 1
  3. 从 j 开始向右, 找到 a[j] < value 的位置
  4. 找到, 交换 i, j 两位置的值, 再返回到第 2 步
  5. 没有找到, 交换 i, end 两位置的值

第二种:

  1. 设置比较点 value = a[end], pos = end, i = begini, j = end
  2. 从左开始找到 >= value 的数的位置 i , a[i] = a[pos], pos = i
  3. 从右开始找到 < value 的数的位置 j, a[j] = a[pos], pos = j
  4. 没有结束,返回到第2步

第一种,可能要少些交换次数, 快排是一种分治法,分治法结构是一个 tree 递归结构,即排序过程展开是一个树状结构.

把代码放在下面:

#include <stdio.h>

void swap(int *a, int i, int j)
{
	int v = a[i];
	a[i] = a[j];
	a[j] = v;

}

int quick_sort2(int *a, int begin ,int end)
{
	if(begin >= end){
		return 0;
	}
	int i;
	int j;
	int value = a[end];
	i = begin;
	while(a[i] < value && i < end){
		i++;
	}
	for(j = i+1; j < end; ){
		if(a[j] < value){
			swap(a, i, j);
			i++;
		}
		j++;
	}
	swap(a,i, end);
	quick_sort2(a, begin, i - 1);
	quick_sort2(a, i+1, end);
	return 0;

}

int quick_sort(int *a, int begin ,int end)
{

	if(begin >= end){
		return 0;
	}
	int i;
	int j;
	int value = a[end];
	for(i = begin, j = end; i < j; ){
		while(a[i] < value && i < j){
			i++;
		}
		a[j] = a[i];
		while(a[j] >= value && i < j){
			j--;
		}
		a[i] = a[j];

	}
	a[i] = value;
	quick_sort(a, begin, i - 1);
	quick_sort(a, i+1, end);
	return 0;
}

void show(int *a, int size)
{
        int i;
	for(i = 0; i <= size; i++){
		printf("%d ", a[i]);
	}
	printf("\n");
}

int main(){

	int a[] = {1, 2, 3, 4, 1, 3, 4, 5, 10, 11, 13, 234, 3,5,7,4,2,1,8,9,6};
	int size= sizeof(a)/sizeof(int)- 1;
	quick_sort(a, 0, size);
        show(a, size);
        quick_sort2(a, 0, size);
	show(a, size);
	return 0;
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值