排序-----快速排序

快速排序是一种非常高效的排序算法,原理为:对于一组给定的数据,取一个基准值,把小于基准值的数放到前部分,大于基准值的放到后部分,其中前部分的所有数都不大于后部分任意一个数,然后再依次对前后两部分的数进行快排,递归该过程,直到序列中的所有数均为有序为止。

以数组{4,6,3,1,2,7,8,9,5}为例:

第一步:以4为基准值,[2,1,3] 4 [6,7,8,9,5]

第二步:分别以2,6为基准值,[1] 2 [3] 4 [5] 6 [7,8,9]

第三步:以7为基准值,1,2,3,4,5,6,7,[8,9]

第四步:以8为基准值,1,2,3,4,5,6,7,8,9

平均时间复杂度为O(nlogn),平均空间复杂度O(logn)

1.

//快速排序
#include<stdio.h>

void Sort(int a[], int low, int high)
{
	if (low >= high)
		return;
	int i = low;
	int j = high;
//取a[i]为基准关键字
	int index = a[i];
//把小于index的数分到前面,大于Index的数分到后面
	while (i < j)
	{
		while (i<j && a[j] > index)
			--j;
		if (i < j)
			a[i++] = a[j];
		while (i < j && a[i] < index)
			++i;
		if (i < j)
			a[j--] = a[i];
	}
	a[i] = index;
//继续进行排序,直到每一组的个数为1时
	Sort(a, low, i - 1);
	Sort(a, i + 1, high);
}
//进行快速排序
void QuickSort(int a[], int len)
{
	Sort(a, 0, len - 1);
}

int main()
{
	int array[] = { 1,4,7,9,2,3,5,8 };
	int len = sizeof(array) / sizeof(array[0]);
	QuickSort(array,len);
	for (int i = 0;i < len;++i)
		printf("%d ", array[i]);
	printf("\n");
	return 0;
}

2.普通版本:

#define LENGTH 10
#include <stdio.h>
#include <stdlib.h>
void Swap(int *a, int low, int high)
{
	int temp = a[low];
	a[low] = a[high];
	a[high] = temp;
}

int Partition(int *a, int low, int high)
{
	int flag = a[low];
	while (low < high)
	{
		while (low<high&&a[high]>flag)
			--high;
		Swap(a, low, high);
		while (low < high&&a[low] < flag)
			++low;
		Swap(a, low, high);
	}
	return low;
}
void QSort(int *a, int low, int high)
{
	int p;
	if (low < high)
	{
		p = Partition(a, low, high);
		QSort(a, low, p - 1);
		QSort(a, p + 1, high);
	}
}
void QuickSort(int *a)
{
	QSort(a, 0, LENGTH - 1);
}


int main()
{
	int i;
	int array[LENGTH] = { 1,3,5,7,9,2,4,6,8,10 };
	
	printf("Before Sorting:\n");
	for (i = 0;i < LENGTH;++i)
		printf("%d ", array[i]);
	printf("\n");

	QuickSort(array);
	printf("After Sorting:\n");
	for (i = 0;i < LENGTH;++i)
		printf("%d ", array[i]);
	printf("\n");
	return 0;
}

3.优化版本:

#define LENGTH 10
#include <stdio.h>
#include <stdlib.h>
void Swap(int *a, int low, int high)
{
	int temp = a[low];
	a[low] = a[high];
	a[high] = temp;
}

int Partition(int *a, int low, int high)
{
//三数取中,保证选到一个比较合适的flag;
	int mid = low+(high-low)/2;
	if (a[low] > a[high])
		Swap(a, low, high);
	if (a[mid] > high)
		Swap(a, mid, high);
	if (a[mid] > a[low])
		Swap(a, mid, low);
	int flag = a[low];
	int p = a[low];
	while (low < high)
	{
		while (low<high&&a[high]>flag)
			--high;
//优化不必要的交换
		a[low] = a[high];
		while (low < high&&a[low] < flag)
			++low;
		a[high] = a[low];
	}
	a[low] = p;
	return low;
}
void QSort(int *a, int low, int high)
{
	int p;
	if (low < high)
	{
		p = Partition(a, low, high);
		QSort(a, low, p - 1);
		QSort(a, p + 1, high);
	}
}
void QuickSort(int *a)
{
	QSort(a, 0, LENGTH - 1);
}


int main()
{
	int i;
	int array[LENGTH] = { 1,3,5,7,9,2,4,6,8,10 };
	
	printf("Before Sorting:\n");
	for (i = 0;i < LENGTH;++i)
		printf("%d ", array[i]);
	printf("\n");

	QuickSort(array);
	printf("After Sorting:\n");
	for (i = 0;i < LENGTH;++i)
		printf("%d ", array[i]);
	printf("\n");
	return 0;
}

4.尾递归优化

#define LENGTH 10
#include <stdio.h>
#include <stdlib.h>
void Swap(int *a, int low, int high)
{
	int temp = a[low];
	a[low] = a[high];
	a[high] = temp;
}

int Partition(int *a, int low, int high)
{
	int flag = a[low];
	while (low < high)
	{
		while (low<high&&a[high]>flag)
			--high;
		Swap(a, low, high);
		while (low < high&&a[low] < flag)
			++low;
		Swap(a, low, high);
	}
	return low;
}
void QSort(int *a, int low, int high)
{
	int p;
	while (low < high)
	{
		p = Partition(a, low, high);
		QSort(a, low, p - 1);
//对QSort进行尾递归优化
		low = p + 1;
	}
}
void QuickSort(int *a)
{
	QSort(a, 0, LENGTH - 1);
}


int main()
{
	int i;
	int array[LENGTH] = { 1,3,5,7,9,2,4,6,8,10 };
	
	printf("Before Sorting:\n");
	for (i = 0;i < LENGTH;++i)
		printf("%d ", array[i]);
	printf("\n");

	QuickSort(array);
	printf("After Sorting:\n");
	for (i = 0;i < LENGTH;++i)
		printf("%d ", array[i]);
	printf("\n");
	return 0;
}

因为采用迭代而不是递归,可以缩减堆栈深度,提高整体性能。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值