前言
分治法–快速排序(C++)
一、快速排序
快速排序作为应用分治法的完美例子,其主要是按照记录的值对序列进行划分,相比较归并排序,其实快速排序更是一种更为巧妙的方式实现了分而治之的思想。
1.问题
应用快速排序对一个无序的序列进行升序排序。
序列:
2.思路
这位仁兄讲的实在生动形象,可以参考理解一下。其实好像是来自《啊哈算法》的。https://blog.csdn.net/xyj2014/article/details/78836888
二、源码(C++)
//分治法--快速排序
#include <iostream>
using namespace std;
//划分
int Partition(int r[], int first, int end)
{
int i = first, j = end;
while (i < j)
{
//右侧扫描
while (i < j && r[i] < r[j])j--;
if (i < j)
{
int temp = r[i]; r[i] = r[j]; r[j] = temp; //交换值,较小值在交换至前面
i++;
}
//左侧扫描
while (i < j && r[i] < r[j])i++;
if (i < j)
{
int temp = r[i]; r[i] = r[j]; r[j] = temp; //交换值,较大值在交换至后面
j--;
}
}
return i;
}
//快速排序
void QuickSort(int r[],int first,int end)
{
int pivot;
if (first < end)
{
pivot = Partition(r, first, end);
QuickSort(r, first, pivot-1);
QuickSort(r, pivot+1, end);
}
}
int main()
{
//输入输出 测试数组
int BeginTestList = 0, LenTestList;
cout << "请输入你要测试的数值长度:";
cin >> LenTestList;
int* TestList = new int[LenTestList];
cout << "请输入要测试的数组值:" ;
for (int i = 0; i < LenTestList; i++)
{
cin >> TestList[i];
}
cout << "测试数组值(未排序):";
for (int i = 0; i < LenTestList; i++)
{
cout << TestList[i] << " ";
}
cout << endl;
//快速排序
QuickSort(TestList, BeginTestList, LenTestList-1);
cout << "测试数组值(已排序):";
for (int i = 0; i < LenTestList; i++)
{
cout << TestList[i] << " ";
}
//释放空间
delete[]TestList;
return 0;
}
三、算法分析
最好的情况就是每次划分是等子序列,即左侧前子序列的长度与右侧后子序列长度相同。在具有n个记录的序列中,一次划分需要对整个待划分的序列扫描一遍,所需的时间为O(n)。设T(n)是对n个记录的序列进行排序的时间,每次划分后,正好把待划分区间划分为两个等长的子序列,则
最坏的情况就是待排序列正序或者逆序,每次划分只得到一个比上次序列少一个的子序列,另一半序列为空序列。则需要经过n-1次递归调用,才能把所有的记录定位下来。第i趟划分需要经过n-i趟比较才能确定第i个记录的位置,因此,其时间复杂度为:
平均时间性能,采用归纳法证明,可知其数量级为
总结
就这样吧,写得非常粗糙,希望假期有空能够重新整理一下。