1 快速排序简介
快速排序的最坏情况的运行时间为O(n^2),虽然这个最坏情况运行时间比较差。
但快速排序通常是用于排序的最佳的实用选择.这是因为其平均性能相当好.期望的
运行时间为O(nlgn)并且隐含的常数因子比较小.并且快速排序是就地排序.
2 快速排序过程
快速排序基于以下分治模式:
(i) 分解 : 数组A[p,r]被划分为两个子数组A[p,q-1](所有元素小于A[q])和A[q+1,r](所有元素大于A[q]),
(ii)解决 : 通过递归调用快速排序.对子数组A[p,q-1]和A[q+1,r]进行排序.
(iii)合并:由于是原地排序因此不需要合并.
3 代码实现
#ifndef __QUICKSORT_H__
#define __QUICKSORT_H__
#include <malloc.h>
#include <cstdio>
#include <time.h>
#include <stdlib.h>
class Quicksort
{
int* m_data;
int m_arraySize;
public:
Quicksort(int size);
~Quicksort();
void Sort(int start,int end);
bool Verify();
int Partition(int start,int end);
void Create();
};
#endif
#include "Quicksort.h"
Quicksort::Quicksort(int size)
{
m_arraySize = size;
m_data = (int *)malloc(sizeof(int)*size);
}
Quicksort::~Quicksort()
{
if(m_data)
{
free(m_data);
}
}
void Quicksort::Sort(int start,int end)
{
int q;
if(start < end)
{
q = Partition(start,end);
Sort(start,q-1);
Sort(q+1,end);
}
}
int Quicksort::Partition(int start,int end)
{
int x = m_data[end];
int i = start-1;
int swapTmp;
for(int j= start;j<end;j++)
{
if(m_data[j]<=x)
{
i++;
swapTmp = m_data[i];
m_data[i] = m_data[j];
m_data[j] = swapTmp;
}
}
swapTmp = m_data[i+1];
m_data[i+1] = m_data[end];
m_data[end] = swapTmp;
return i+1;
}
bool Quicksort::Verify()
{
int oldValue = m_data[0];
for(int i=1;i<m_arraySize;i++)
{
if(m_data[i]<oldValue)
{
return false;
}
oldValue = m_data[i];
}
return true;
}
void Quicksort::Create()
{
srand((unsigned)time(NULL));
for(int i=0;i< m_arraySize;i++)
{
m_data[i] = rand();
}
}
#include "Quicksort.h"
int main()
{
int size = 1000 * 1000;
Quicksort pSort(size);
pSort.Create();
pSort.Sort(0,size-1);
if(pSort.Verify())
{
printf("success \n");
}
else
{
printf("error \n");
}
return 0;
}
4 性能分析
(i) 最佳情况 :每一次划分得到的两个子数组大小相等。此时快速排序的时间为O(nlgn)
(ii)最坏情况 :每次划分的n个元素被划分成长度为1和n-1的两个子数组,此时快速排序的时间为O(n^2)
(iii)平均情况:输入数组是随机的,此时快速排序的运行时间为O(nlgn).此时常数因子略大于最佳情况.