快速排序

快速排序基本思想:

简介:Quicksort (sometimes called partition-exchange sort) is an efficient sorting algorithm. Developed by British computer scientist Tony Hoare in 1959[1] and published in 1961,[2] it is still a commonly used algorithm for sorting. When implemented well, it can be about two or three times faster than its main competitors, merge sort and heapsort
-----from wiki
快速排序也是分治算法的一种,而且在现实中应用很广泛,很多语言的qsort就是快排的优化版本

图片来自维基百科https://en.wikipedia.org/wiki/Quicksort#/media/File:Sorting_quicksort_anim.gif
图片来自维基百科[(htps://en.wikipedia.org/wiki/Quicksort#/media/File:Sorting_quicksort_anim.gif)]

1、数组划分

核心思想:

  1. 选取固定位置的主元x(如尾元素)
  2. 维护两个部分的右端下标i,j
  3. 比较A[j] 和 x的大小
    if: A[j] <= x : swap(A[i+1], A[j]), i,j都向后移动
    if: A[j] > x : j 向后移动
    注:A[i+1] 是大数区最左边的一个数。

实现方法

  • 选取固定位置主元𝒙(如尾元素)
  • 维护两个部分的右端点变量𝒊,𝒋
  • 考察数组元素𝑨 𝒋 ,只和主元比较
    若𝑨 𝒋 ≤ 𝒙,则交换𝑨[𝒋]和𝑨[𝒊 + 𝟏],𝒊,𝒋右移
    若𝑨 𝒋 > 𝒙,则𝒋右移
  • 把主元放在中间作分界线
2、伪代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、算法实现
#include<iostream> 
using namespace std;
int a[20]={0,1,2,3,4,5,6,7,8,9};
int Partition(int A[], int p, int r) // 数组划分,r是主元的位置,固定选取 
{
	// p是起始位置,r是选取的主元的位置
	int x = A[r]; // x即为主元
	int i = p - 1;
	for (int j = p; j < r; j++) {
		if (A[j] <= x) {
			swap(A[j], A[i+1]);
			i++; // i右移 
		}
//		else {
//		如果A[j] > x, 只需要j右移	 
//		}
	} 
	swap(A[i+1], A[r]);//交换大数区最左边(A[i+1])和主元 
	int q = i+1;
	return q; // 返回的是大数区左边界的值 
	
}
void QuickSort(int A[], int p, int r) // 快速排序主函数 
{
	if (p < r){
		int q = Partition(A, p, r); // q是主元的下标 
		QuickSort(A, p, q-1); // 对主元左边排序 
		QuickSort(A, q+1, r); // 对主元右边排序 
	}
} 
int main()
{
	QuickSort(a,0,9);
	for (int i = 0; i < 10; i++) {
		cout << a[i] << " " << endl;
	}
	return 0;
}
4、时间复杂度分析

最好:
每次选取的主元都在中间,子问题规模变成原来的1/2
T ( n ) = 2 T ( n 2 ) + n T(n)=2T(\dfrac{n}{2})+n T(n)=2T(2n)+n
时间复杂度是: O ( n l o g n ) O(nlogn) O(nlogn)

最坏:
每次选取的主元都在最后,子问题规模每次减1:
T ( n ) = T ( n − 1 ) + T ( 0 ) + n T(n)=T(n-1)+T(0)+n T(n)=T(n1)+T(0)+n
时间复杂度是: O ( n 2 ) O(n^2) O(n2)

随机化快速排序:

相较于上面的变化是:主元的选取不再是最后一个,而是随机选取

1、 伪代码

在这里插入图片描述

2、算法实现
#include<iostream> 
#include<cstdio>
#include<cstdlib>
using namespace std;
int a[20]={0,1,2,3,4,5,6,7,8,9};
int Partition(int A[], int p, int r) // 数组划分,r是主元的位置,固定选取 
{
	// p是起始位置,r是选取的主元的位置
	int x = A[r]; // x即为主元
	int i = p - 1;
	for (int j = p; j < r; j++) {
		if (A[j] <= x) {
			swap(A[j], A[i+1]);
			i++; // i右移 
		}
//		else {
//		如果A[j] > x, 只需要j右移	 
//		}
	} 
	swap(A[i+1], A[r]);//交换大数区最左边(A[i+1])和主元 
	int q = i+1;
	return q; // 返回的是大数区左边界的值 
	
}
void QuickSort(int A[], int p, int r) // 快速排序主函数 
{
	if (p < r){
		int q = Partition(A, p, r); // q是主元的下标 
		QuickSort(A, p, q-1); // 对主元左边排序 
		QuickSort(A, q+1, r); // 对主元右边排序 
	}
} 

// 随机化快速排序:随机选取主元 
int Randomized_Partition(int A[], int p, int r)
{
	int s = (rand() % (r-p+1)) + p;
	swap(A[s], A[r]); // 令A[s]作为主元
	int q = Partition(A, p, r);
	return q; 
}
//
void Randomized_Qsort(int A[], int p, int r)
{
	if (p < r) {
		int q = Randomized_Partition(A, p, r);
		Randomized_Qsort(A, p, q-1);
		Randomized_Qsort(A, q, r);
	}
} 
 

int main()
{
	Randomized_Qsort(a,0,9);
	for (int i = 0; i < 10; i++) {
		cout << a[i] << " " << endl;
	}
	return 0;
}
3、时间复杂度分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值