分治算法之快速排序

分治算法之快速排序

上一篇:分治算法之二分查找【含例题】

快速排序

概述

快速排序是对冒泡排序的改进,和冒泡排序一样,同属于交换排序。

其主要包括

(1) Divide: 分割成两个子数组
(2) Conquer: 递归处理两个子数组
(3) Combine: 连接在一起

在这里插入图片描述

核心思想

  • 数据分区:一部分比另一部分小
  • 递归排序:递归处理两部分

实例分析

在这里插入图片描述

伪代码

分区函数 Partition(A, p, q)
在这里插入图片描述

快速排序函数:QuickSort(A, p ,q)

在这里插入图片描述

时间复杂度

  • 最坏情况(划分为1和n-1两段):O(n^2)

  • 最好情况(划分成两段都为n/2):O(nlogn)

  • 一般情况(按照一定的比例划分,例如1/10 : 9/10):O(nlogn)

平均时间复杂度:T(n) = O(nlogn)

核心代码

main函数

int main()
{
    int a[] = {6, 10, 13, 5, 8, 3, 2, 11};
    quickSort(a,0,7);
	for(int i=0; i<=7; i++)
	{
		printf("%d ",a[i]);
	}
	return 0;
}

快速排序函数

void quickSort(int a[], int p, int q)
{
	if(p < q)
	{
		int r = partition(a, p, q);
		quickSort(a, p, r-1);
		quickSort(a, r+1, q);
	}
}

分区函数

int partition(int a[], int p, int q)
{
	int x = a[p];
	int i = p, j;
	for(j = p + 1;j <= q; j++)
	{
		if(a[j]<=x) 
        {
			i++;
			swap(a,i,j);
		}
	}
	swap(a,p,i);
	return i;
}

交换函数

int swap(int a[], int i, int j)
{
	int temp = a[i];
	a[i] = a[j];
	a[j] = temp;
}

算法改进——随机化快速排序

当分区出现最坏情况(划分为1和n-1两段),时间复杂度为O(n^2),显然这种情况是不快速排序想要的。接下来我们就看随机化快速排序

  • 快速排序算法的性能取决于划分的对称性
  • 通过修改算法Partition,可以设计出采用随机选择策略的快速排序算法
  • 在A[p…q]中随机选出一个元素作为划分基准

随机化快速排序的时间复杂度为:T(n) = O(nlogn)

产生随机数函数

  • 已知rand()函数可以随机生成一个非负整数

  • 产生[a,b]之间的随机非负整数:rand%(b-a+1)+a

  //rand()函数的用法。 
  /* 输出 0 到 49 之间的 5 个随机数 */
     for( i = 0 ; i < 5 ; i++ ) {
        printf("%d\n", rand() % 50);
     }

随机化快速排序函数

  void randomizedQuickSort(int a[], int p, int q)
  {
  	if(p < q)
  	{
  		int r = randomizedPartition(a, p, q);
  		randomizedQuickSort(a, p, r-1);
  		randomizedQuickSort(a, r+1, q);
  	}
  }

分区函数

int randomizedPartition(int a[], int p, int q)
{
	int r = random(p,q);
	swap(a,p,r);
	int i = partition(a, p, q);
	return i;
}

产生随机数

int random(int p, int q)
{
	return rand()%(q-p+1) + p;
}

如有错误,恳请指正
最后,如果这篇文章对你有帮助,欢迎一键三连

要么努力,要么放弃

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱笑君吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值