排序方法(二)快速排序

使用语言:c语言,编译器visual studio 2017
一.基本思想
假设由小到大排序。则快速排序的基本思想是,用一个左指针(或下标)记录最左边的数,用一个右指针记录最右边的数。选取一个数作为基数(随机取即可,我取的是第一个数),实现基数左边的都不大于基数,基数右边的都不小于基数,再递归地分别对基数左右的数进行快速排序,最后得到排序完毕的序列。具体实现过程:
(1)设数组为array[],设左下标为i,右下标为j,以array[i]为基数;
(2)首先j向左遍历,找到不大于基数的数就停止;
(3)i向右遍历,找到不小于基数的数就停止;
(4)交换array[i]和array[j]的位置,交换后基数需要设置成array[j];//这样确保基数是同一个数
(5)循环执行(2)、(3)、(4),直到i和j相等。

二.代码实现

#include<stdio.h>
using namespace std;
void swap(int i, int j, int array[]) {//交换array[i]和array[j]
	int temp = array[i];
	array[i] = array[j];
	array[j] = temp;
}

//left向右查找不小于基准的数;right向左查找不大于基准的数
void QuickSort(int left,int right, int array[]) {
	int i = left;
	int j = right;
	int base = array[i];
	if (left >= right) return;
	while (i != j) {
		while (j > i&&array[j] >= base) {
			j--;
		}
		swap(i, j, array);
		base = array[j];
		while (i < j&&array[i] <= base) {
			i++;
		}
		swap(i, j, array);
		base = array[i];
	}
	QuickSort(left, i - 1, array);
	QuickSort(i + 1, right, array);
}

int main()
{
	int array[100];
	int i = 0;
	int j = 0;
	int num = 0;
	printf("请输入待排序的数字个数:\n");
	scanf_s("%d", &num);
	printf("请输入%d个数字:\n", num);
	for (i; i<num; i++) scanf_s("%d", &array[i]);
	i = 0;
	j = num - 1;
	QuickSort(i, j, array);
	for (int k = 0; k < num; k++) {
		printf("%d ", array[k]);
		if (k == num - 1) printf("\n");
	}
	return 0;
}

三.时间复杂度分析
这里参考博客surgewong的博客
当基数不能很好的分割序列,比如分割后的两个序列分别拥有1个和n-1个元素,那么快速排序就退化成冒泡排序,这是最差的情况,时间复杂度为O(N^2)。
设T(n)为对n个记录进行排序所需要的时间,则每当一个记录得到其正确位置,整组大致分成两个相等的两部分时,我们得到快速排序算法的最佳时间复杂性:
T(n) <= cn + 2T(n/2) c是一个常数

<= cn + 2(cn/2+2T(n/4)) = 2cn+ 4T(n/4)

<= 2cn + 4(cn/4+ 2T(n/8)) = 3cn + 8T(n/8)

…… ……

<= cnlogn + nT(1) = O(nlogn) 其中cn 是一次划分所用的时间,c是一个常数
 最坏的情况,每次划分都得到一个子序列,时间复杂度为:

T(n) = cn + T(n-1)

= cn + c(n-1) + T(n - 2) = 2cn -c + T(n-2)
= 2cn - c + c(n-2) + T(n-3)= 3cn - 3c + T(n-3)

……

= c[n(n+1)/2-1] + T(1) = O(n2)

快速排序的时间复杂度在平均情况下介于最佳与最差情况之间,假设每一次分割时,基准值处于最终排序好的位置的概率是一样的,基准值将数组分成长度为0 和 n-1,1 和 n-2,……的概率都是 1/n。在这种假设下,快速排序的平均时间复杂性为:

T(n) = cn + 1/n(T(k)+ T(n-k-1)) T(0) = c, T(1) = c

这是一个递推公式,T(k)和T(n-k-1)是指处理长度为 k 和 n-k-1 数组是快速排序算法所花费的时间, 根据公式所推算出来的时间为 O(nlogn)。因此快速排序的平均时间复杂性为O(nlogn)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值