中科大软件学院算法实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法实验报告
快速排序
1. 问题描述:
实现对数组的普通快速排序与随机快速排序
(1)实现上述两个算法
(2)统计算法的运行时间
(3)分析性能差异,作出总结
2. 算法原理:
2.1快速排序
快速排序是对冒泡排序的一种改进。它的基本思想是:选取一个基准元素,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比基准元素小,另外一部分的所有数据都要比基准元素大,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
设要排序的数组是A[0]……A[N-1],首先选取一个数据(普通快速排序选择的是最后一个元素, 随机快速排序是随机选择一个元素)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。
一趟快速排序的算法是:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]赋给A[i];
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]赋给A[j];
5)重复第3、4步,直到i=j;(3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i,j指针位置不变。另外,i==j这
一过程一定正好是i+或j-完成的时候,此时令循环结束)。
2.2随机快速排序
快速排序的最坏情况基于每次划分对主元的选择。基本的快速排序选取第一个或者最后一个元素作为主元。这样在数组已经有序的情况下,每次划分将得到最坏的结果。一种比较常见的优化方法是随机化算法,即随机选取一个元素作为主元。这种情况下虽然最坏情况仍然是O(n^2),但最坏情况不再依赖于输入数据,而是由于随机函数取值不佳。实际上,随机化快速排序得到理论最坏情况的可能性仅为1/(2^n)。所以随机化快速排序可以对于绝大多数输入数据达到O(nlogn)的期望时间复杂度。
3. 实验数据
本实验采用对80,000个随机数据进行十次排序,并取出平均值。分别用普通快速排序和随机快速排序对数据排序。用毫秒作为运行计数单位,观测两种算法所用的时间的不同。
4. 实验截图
如下图所示的时间,普通快速排序所用的平均时间为181毫秒,而随机化版本的快速排序所用时间仅仅为119毫秒。
5. 结果分析
5.1 时间分析
从实验截图得到的结果来看,随机化版本的快速排序所用时间比普通快速排序所用的平均时间少。
快速排序的平均时间复杂度为O(nlogn),最坏时间时间可达到O(n^2),最坏情况是当要排序的数列基本有序的时候。根据快速排序的工作原理我们知道,
选取第一个或者最后一个元素作为主元,快速排序依次将数列分成两个数列,然后递归将分开的数列进行排序。当把数列平均分成两个等长的数列时,效率是最高的,如果相差太大,效率就会降低。
我们通过使用随机化的快速排序随机的从数列中选取一个元素与第一个,或者最后一个元素交换,这样就会使得数列有序的概率降低。
随机化快速排序的平均时间复杂度为O(nlogn),最坏时间时间也会达到O(n^2),这种机率已经降得很小。
5.2 空间分析
普通快速排序与随机快速排序在对序列的操作过程中都只需花费常数级的空间。空间复杂度S(1)。但需要注意递归栈上需要花费最少logn 最多n的空间
6源码
快速排序源码C++实现
#include
#include
using namespace std;
void QuickSort(int arr[],int lo,int hi)
{
//这里的lo和hi是数组的下标;
if(lo>=hi) {return;}
int fi = lo;//0开始
int la = hi;//最大下标开始
int key = arr[fi];
while(fi < la)
{
while(fi
--la;
arr[fi] = arr[la];
while(fi ++fi; arr[la] = arr[fi]; } arr[fi] = key; QuickSort(arr,lo,fi-1); QuickSort(arr,fi+1,hi); } int main() { int arr[100000],n; cout<<"请输入要排序的个数(您不能够超过100000个数字):"< cin>>n; for(int i = 0;i { arr[i]=rand(); } FILETIME beg,end; GetSystemTimeAsFileTime(&beg); QuickSort(arr,0,n-1); GetSystemTimeAsFileTime(&end); for(int i= 0;i cout< cout< cout<<"当输入"< "<<100*(end.dwLowDateTime-beg.dwLowDateTime)<<"us"< return 0; } 随机快速排序源码C++实现 #include #include #include using namespace std; void RadomQuickSort(int arr[], int lo, int hi) { if(lo>=hi) return; int ram=(int)(rand()%(hi-lo+1))+lo; int key=arr[ram]; arr[ram]=arr[hi]; arr[hi]=key; int x = arr[hi]; int i = lo - 1; for (int j = lo; j < hi; j++) { if (x >= arr[j]) { i++; int t=arr[i];