快速排序的描述
快速排序的最坏情况的时间复杂度为Θ(n^2),但是快速排序是实际排序应用中最好的选择,因为快速排序的平局性能非常好,而且我们将快速排序算法设计为随机算法的话,其期望时间复杂度是Θ(nlgn),而且Θ(nlgn)中隐含的常数因子非常小。另外,快速排序还是一种原址排序(具体分析见文章——);
首先快速排序是一种基于分治的排序方法,其三部分治过程为:
分解:将待排序数组分解为两个分数组,其中前一个分数组中的元素小于中间元素,后一个分数组中的元素均大于中间元素,且分数组可能为空数组;与归并排序不同的是,快速排序将排序的过程实现在分解的过程中,分解过程实现了对数组的原址排序;PARTITION过程如下:
PARTITION(A,Alength,Ahead)
PARTITION(A,Alength,Ahead)
x=A[Alength];//从数组尾取分割元素
i=Ahead;
for(j=i to A.length)// 将待排数组内小于分割元素换到A[0]~A[i]内
{ if(A[j]≤x)
{ swap A[j] with A[i];
i++; }
}
swap x with A[i];//将中间元素x换到A[i]处(退出循环时已经将i的值加一)
return i;
//此时数组A已经被分为三部分:≤A[i], A[i], ≥A[i](两边的两部分可能有空数组,但不会全为空数组)
解决:递归调用快速排序,分别对左右两个子数组进行快速排序
合并:由于是原址排序,不需要进行合并操作,最后一次排序完成后即排序完成;
快速排序的伪码:
QUICKSORT(A,Alength, Ahead)
if (Alength>Ahead)
{ midnum=PARTITION(A,Alength,Ahead)
PARTITION(A,midnum-1,Ahead)//注意此处的Ahead是上层递归中的Ahead,而不是首层递归中的,下句中的Alength也一样
PARTITION(A,Alength,midnum+1)
}
实现如下:
// quicksort.cpp
#include "stdafx.h"
#include <iostream>
using namespace std;
int PARTITION(int *B, int Ahead1, int Atail)
{
int x = B[Atail];
int i = Ahead1;
for (int j = i; j < Atail; j++)
{
if (B[j] < x)
{
int temp1 = B[i];
B[i] = B[j];
B[j]=temp1;
i++;
}
}
int temp0 = B[i];
B[i] = x;
B[Atail] = temp0;
return i;
}
void QUICKSORT(int * A, int Ahead, int Alength)
{
if (Ahead < Alength)
{
int midnum = PARTITION(A, Ahead, Alength);
QUICKSORT(A, Ahead,( midnum - 1));
QUICKSORT(A, (midnum + 1), Alength);
}
}
int main()//输出测试
{
int num;
cout << "please input the number of the array:\n";
cin >> num;
int *A=new int [num];
int head = 0;
int tail = num-1;
cout << "please input the array:\n";
for (int i = 0; i < num; i++)cin >> A[i];
cout << "the result is:\n";
QUICKSORT(A, head, tail);
for (int i = 0; i < num; i++)cout << A[i] << '<';
return 0;
}