18-快速排序

快速排序也是分治的典型应用

1、任务分解

数组排序任务可以如下完成:

  1. 设k=a[0], 将k挪到适当位置,使得比k小的元素都在k左边,比k大的元素都在k右边,和k相等的,不关心
    在k左右出现均可(O(n)时间完成)
  2. 把k左边的部分快速排序
  3. 把k右边的部分快速排序

2、快排过程

下面使用实例来说明快速排序的过程。
1、首先取第一个数作为参考节点,左侧下标在最左边,右侧下下标在最右边。
2、右侧下标对应的值与参考节点相比较,如果大于等于参考节点,下标向左移动,直到右侧下标对应值小于参考节点,这时将右侧下表与参考节点位置上的值交换。
3、左侧下标与参考节点比较,如果小于等于参考节点,左侧下标向右移动。直到左侧下标对应值大于参考节点,交换左侧下表与参考节点中的值。
在这里插入图片描述

#include<iostream>
using namespace std;
typedef int ElementType;

void Qsort(ElementType a[],int left,int right)
{
	if (left >= right)
		return;
	ElementType privot=a[left];

	int low=left, high=right;
	while(low<high)
	{
		while (a[high] >= privot&&low<high){ high--; }
		swap(a[low], a[high]);
		while (a[low] <= privot&&low<high){ low++; }
		swap(a[low], a[high]);
	}
	Qsort(a, left, low - 1);
	Qsort(a,low+1,right);
}

void Quick_sort(ElementType a[], int n)
{
	Qsort(a,0,n-1);
}


int main()
{
	int a[] = { 6, 8, 2, 5, 7, 9, 0, 1, 3, 4  };
	int len = sizeof(a) / sizeof(a[0]);
	Quick_sort(a, len);
	for (int i = 0; i < len; i++)
		cout << a[i] << " ";
	return 0;
}

快速排序的时间复杂度分析
在排序之前我问要选择参考点,然后根据参考点将元素分成两部分,分别进行排序,我们假设两部分是等分的,分析复杂度和上一篇文章中归并排序复杂度相同:
对n个元素进行排序的时间:
T(n) = 2*T(n/2) + n
= 2*(2*T(n/4)+n/2)+n
= 4*T(n/4)+2*n
= 4*(2*T(n/8)+n/4)+2*n
= 8*T(n/8)+3*n

= 2k *T(n/2k)+k*n

一直到n/2k = 1 (此时k = log2n)
T(n)= 2k *T(1)+k*n
= 2k+k*n
= n+(log2n)*n

复杂度为O(nlogn)

看一下最坏的情况,假设我们将元素分为两份,每次选取的参考点都是最小值或者最大值,也就是将元素分为1和n-1两份。
T(n) = 1+T(n-1) + n
= 1+(1+T(n-2)+n-1)+n
= 2+T(n-2)+n+n-1
= 2+(1+T(n-3)+n-2)+n+n-1
= 3+T(n-3)+n+n-1+n-2

= n-1+T(1)+n+n-1+n-2+……+2
=(n2+3*n-2)/2

复杂度为O(n2)

猜你喜欢

转载自blog.csdn.net/happyjacob/article/details/88094948